ASoC: Intel: Add PM support to HSW/BDW IPC driver
[deliverable/linux.git] / sound / soc / intel / sst-haswell-pcm.c
CommitLineData
a4b12990
MB
1/*
2 * Intel SST Haswell/Broadwell PCM Support
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <linux/slab.h>
a4b12990
MB
20#include <linux/delay.h>
21#include <asm/page.h>
22#include <asm/pgtable.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/dmaengine_pcm.h>
27#include <sound/soc.h>
28#include <sound/tlv.h>
29#include <sound/compress_driver.h>
30
31#include "sst-haswell-ipc.h"
32#include "sst-dsp-priv.h"
33#include "sst-dsp.h"
34
35#define HSW_PCM_COUNT 6
36#define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
37
38/* simple volume table */
39static const u32 volume_map[] = {
40 HSW_VOLUME_MAX >> 30,
41 HSW_VOLUME_MAX >> 29,
42 HSW_VOLUME_MAX >> 28,
43 HSW_VOLUME_MAX >> 27,
44 HSW_VOLUME_MAX >> 26,
45 HSW_VOLUME_MAX >> 25,
46 HSW_VOLUME_MAX >> 24,
47 HSW_VOLUME_MAX >> 23,
48 HSW_VOLUME_MAX >> 22,
49 HSW_VOLUME_MAX >> 21,
50 HSW_VOLUME_MAX >> 20,
51 HSW_VOLUME_MAX >> 19,
52 HSW_VOLUME_MAX >> 18,
53 HSW_VOLUME_MAX >> 17,
54 HSW_VOLUME_MAX >> 16,
55 HSW_VOLUME_MAX >> 15,
56 HSW_VOLUME_MAX >> 14,
57 HSW_VOLUME_MAX >> 13,
58 HSW_VOLUME_MAX >> 12,
59 HSW_VOLUME_MAX >> 11,
60 HSW_VOLUME_MAX >> 10,
61 HSW_VOLUME_MAX >> 9,
62 HSW_VOLUME_MAX >> 8,
63 HSW_VOLUME_MAX >> 7,
64 HSW_VOLUME_MAX >> 6,
65 HSW_VOLUME_MAX >> 5,
66 HSW_VOLUME_MAX >> 4,
67 HSW_VOLUME_MAX >> 3,
68 HSW_VOLUME_MAX >> 2,
69 HSW_VOLUME_MAX >> 1,
70 HSW_VOLUME_MAX >> 0,
71};
72
73#define HSW_PCM_PERIODS_MAX 64
74#define HSW_PCM_PERIODS_MIN 2
75
76static const struct snd_pcm_hardware hsw_pcm_hardware = {
77 .info = SNDRV_PCM_INFO_MMAP |
78 SNDRV_PCM_INFO_MMAP_VALID |
79 SNDRV_PCM_INFO_INTERLEAVED |
80 SNDRV_PCM_INFO_PAUSE |
81 SNDRV_PCM_INFO_RESUME |
82 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
8e897618 83 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |
a4b12990
MB
84 SNDRV_PCM_FMTBIT_S32_LE,
85 .period_bytes_min = PAGE_SIZE,
86 .period_bytes_max = (HSW_PCM_PERIODS_MAX / HSW_PCM_PERIODS_MIN) * PAGE_SIZE,
87 .periods_min = HSW_PCM_PERIODS_MIN,
88 .periods_max = HSW_PCM_PERIODS_MAX,
89 .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE,
90};
91
e9600bc1
LG
92struct hsw_pcm_module_map {
93 int dai_id;
94 enum sst_hsw_module_id mod_id;
95};
96
a4b12990
MB
97/* private data for each PCM DSP stream */
98struct hsw_pcm_data {
99 int dai_id;
100 struct sst_hsw_stream *stream;
e9600bc1 101 struct sst_module_runtime *runtime;
a4b12990
MB
102 u32 volume[2];
103 struct snd_pcm_substream *substream;
104 struct snd_compr_stream *cstream;
105 unsigned int wpos;
106 struct mutex mutex;
916152c4 107 bool allocated;
e9600bc1 108 int persistent_offset;
a4b12990
MB
109};
110
111/* private data for the driver */
112struct hsw_priv_data {
113 /* runtime DSP */
114 struct sst_hsw *hsw;
115
116 /* page tables */
0b708c87 117 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
a4b12990
MB
118
119 /* DAI data */
120 struct hsw_pcm_data pcm[HSW_PCM_COUNT];
121};
122
916152c4
LG
123static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data);
124
a4b12990
MB
125static inline u32 hsw_mixer_to_ipc(unsigned int value)
126{
127 if (value >= ARRAY_SIZE(volume_map))
128 return volume_map[0];
129 else
130 return volume_map[value];
131}
132
133static inline unsigned int hsw_ipc_to_mixer(u32 value)
134{
135 int i;
136
137 for (i = 0; i < ARRAY_SIZE(volume_map); i++) {
138 if (volume_map[i] >= value)
139 return i;
140 }
141
142 return i - 1;
143}
144
145static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
146 struct snd_ctl_elem_value *ucontrol)
147{
923976a3
LPC
148 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
149 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
a4b12990
MB
150 struct soc_mixer_control *mc =
151 (struct soc_mixer_control *)kcontrol->private_value;
a4b12990
MB
152 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
153 struct sst_hsw *hsw = pdata->hsw;
154 u32 volume;
155
156 mutex_lock(&pcm_data->mutex);
157
158 if (!pcm_data->stream) {
159 pcm_data->volume[0] =
160 hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
161 pcm_data->volume[1] =
162 hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
163 mutex_unlock(&pcm_data->mutex);
164 return 0;
165 }
166
167 if (ucontrol->value.integer.value[0] ==
168 ucontrol->value.integer.value[1]) {
169 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
170 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume);
171 } else {
172 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
173 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
174 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
175 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume);
176 }
177
178 mutex_unlock(&pcm_data->mutex);
179 return 0;
180}
181
182static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
183 struct snd_ctl_elem_value *ucontrol)
184{
923976a3
LPC
185 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
186 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
a4b12990
MB
187 struct soc_mixer_control *mc =
188 (struct soc_mixer_control *)kcontrol->private_value;
a4b12990
MB
189 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
190 struct sst_hsw *hsw = pdata->hsw;
191 u32 volume;
192
193 mutex_lock(&pcm_data->mutex);
194
195 if (!pcm_data->stream) {
196 ucontrol->value.integer.value[0] =
197 hsw_ipc_to_mixer(pcm_data->volume[0]);
198 ucontrol->value.integer.value[1] =
199 hsw_ipc_to_mixer(pcm_data->volume[1]);
200 mutex_unlock(&pcm_data->mutex);
201 return 0;
202 }
203
204 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 0, &volume);
205 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
206 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume);
207 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
208 mutex_unlock(&pcm_data->mutex);
209
210 return 0;
211}
212
213static int hsw_volume_put(struct snd_kcontrol *kcontrol,
214 struct snd_ctl_elem_value *ucontrol)
215{
923976a3
LPC
216 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
217 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
a4b12990
MB
218 struct sst_hsw *hsw = pdata->hsw;
219 u32 volume;
220
221 if (ucontrol->value.integer.value[0] ==
222 ucontrol->value.integer.value[1]) {
223
224 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
225 sst_hsw_mixer_set_volume(hsw, 0, 2, volume);
226
227 } else {
228 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
229 sst_hsw_mixer_set_volume(hsw, 0, 0, volume);
230
231 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
232 sst_hsw_mixer_set_volume(hsw, 0, 1, volume);
233 }
234
235 return 0;
236}
237
238static int hsw_volume_get(struct snd_kcontrol *kcontrol,
239 struct snd_ctl_elem_value *ucontrol)
240{
923976a3
LPC
241 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
242 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
a4b12990
MB
243 struct sst_hsw *hsw = pdata->hsw;
244 unsigned int volume = 0;
245
246 sst_hsw_mixer_get_volume(hsw, 0, 0, &volume);
247 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
248
249 sst_hsw_mixer_get_volume(hsw, 0, 1, &volume);
250 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
251
252 return 0;
253}
254
255/* TLV used by both global and stream volumes */
256static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
257
258/* System Pin has no volume control */
259static const struct snd_kcontrol_new hsw_volume_controls[] = {
260 /* Global DSP volume */
261 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
262 ARRAY_SIZE(volume_map) -1, 0,
263 hsw_volume_get, hsw_volume_put, hsw_vol_tlv),
264 /* Offload 0 volume */
265 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
266 ARRAY_SIZE(volume_map), 0,
267 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
268 /* Offload 1 volume */
269 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
270 ARRAY_SIZE(volume_map), 0,
271 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
272 /* Loopback volume */
273 SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8,
274 ARRAY_SIZE(volume_map), 0,
275 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
276 /* Mic Capture volume */
277 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
278 ARRAY_SIZE(volume_map), 0,
279 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
280};
281
282/* Create DMA buffer page table for DSP */
0b708c87
LG
283static int create_adsp_page_table(struct snd_pcm_substream *substream,
284 struct hsw_priv_data *pdata, struct snd_soc_pcm_runtime *rtd,
285 unsigned char *dma_area, size_t size, int pcm)
a4b12990 286{
0b708c87
LG
287 struct snd_dma_buffer *dmab = snd_pcm_get_dma_buf(substream);
288 int i, pages, stream = substream->stream;
a4b12990 289
0b708c87 290 pages = snd_sgbuf_aligned_pages(size);
a4b12990
MB
291
292 dev_dbg(rtd->dev, "generating page table for %p size 0x%zu pages %d\n",
293 dma_area, size, pages);
294
295 for (i = 0; i < pages; i++) {
296 u32 idx = (((i << 2) + i)) >> 1;
0b708c87 297 u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
a4b12990
MB
298 u32 *pg_table;
299
300 dev_dbg(rtd->dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
301
0b708c87 302 pg_table = (u32 *)(pdata->dmab[pcm][stream].area + idx);
a4b12990
MB
303
304 if (i & 1)
305 *pg_table |= (pfn << 4);
306 else
307 *pg_table |= pfn;
308 }
309
310 return 0;
311}
312
313/* this may get called several times by oss emulation */
314static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
315 struct snd_pcm_hw_params *params)
316{
317 struct snd_soc_pcm_runtime *rtd = substream->private_data;
318 struct snd_pcm_runtime *runtime = substream->runtime;
319 struct hsw_priv_data *pdata =
320 snd_soc_platform_get_drvdata(rtd->platform);
321 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
322 struct sst_hsw *hsw = pdata->hsw;
323 struct sst_module *module_data;
324 struct sst_dsp *dsp;
0b708c87 325 struct snd_dma_buffer *dmab;
a4b12990
MB
326 enum sst_hsw_stream_type stream_type;
327 enum sst_hsw_stream_path_id path_id;
328 u32 rate, bits, map, pages, module_id;
329 u8 channels;
330 int ret;
331
916152c4
LG
332 /* check if we are being called a subsequent time */
333 if (pcm_data->allocated) {
334 ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
335 if (ret < 0)
336 dev_dbg(rtd->dev, "error: reset stream failed %d\n",
337 ret);
338
339 ret = sst_hsw_stream_free(hsw, pcm_data->stream);
340 if (ret < 0) {
341 dev_dbg(rtd->dev, "error: free stream failed %d\n",
342 ret);
343 return ret;
344 }
345 pcm_data->allocated = false;
346
347 pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
348 hsw_notify_pointer, pcm_data);
349 if (pcm_data->stream == NULL) {
350 dev_err(rtd->dev, "error: failed to create stream\n");
351 return -EINVAL;
352 }
353 }
354
a4b12990
MB
355 /* stream direction */
356 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
357 path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
358 else
359 path_id = SST_HSW_STREAM_PATH_SSP0_IN;
360
361 /* DSP stream type depends on DAI ID */
362 switch (rtd->cpu_dai->id) {
363 case 0:
364 stream_type = SST_HSW_STREAM_TYPE_SYSTEM;
365 module_id = SST_HSW_MODULE_PCM_SYSTEM;
366 break;
367 case 1:
368 case 2:
369 stream_type = SST_HSW_STREAM_TYPE_RENDER;
370 module_id = SST_HSW_MODULE_PCM;
371 break;
372 case 3:
373 /* path ID needs to be OUT for loopback */
374 stream_type = SST_HSW_STREAM_TYPE_LOOPBACK;
375 path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
376 module_id = SST_HSW_MODULE_PCM_REFERENCE;
377 break;
378 case 4:
379 stream_type = SST_HSW_STREAM_TYPE_CAPTURE;
380 module_id = SST_HSW_MODULE_PCM_CAPTURE;
381 break;
382 default:
383 dev_err(rtd->dev, "error: invalid DAI ID %d\n",
384 rtd->cpu_dai->id);
385 return -EINVAL;
386 };
387
388 ret = sst_hsw_stream_format(hsw, pcm_data->stream,
389 path_id, stream_type, SST_HSW_STREAM_FORMAT_PCM_FORMAT);
390 if (ret < 0) {
391 dev_err(rtd->dev, "error: failed to set format %d\n", ret);
392 return ret;
393 }
394
395 rate = params_rate(params);
396 ret = sst_hsw_stream_set_rate(hsw, pcm_data->stream, rate);
397 if (ret < 0) {
398 dev_err(rtd->dev, "error: could not set rate %d\n", rate);
399 return ret;
400 }
401
402 switch (params_format(params)) {
403 case SNDRV_PCM_FORMAT_S16_LE:
404 bits = SST_HSW_DEPTH_16BIT;
405 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 16);
406 break;
407 case SNDRV_PCM_FORMAT_S24_LE:
8e897618
JY
408 bits = SST_HSW_DEPTH_32BIT;
409 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 24);
410 break;
411 case SNDRV_PCM_FORMAT_S8:
412 bits = SST_HSW_DEPTH_8BIT;
413 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 8);
414 break;
415 case SNDRV_PCM_FORMAT_S32_LE:
416 bits = SST_HSW_DEPTH_32BIT;
a4b12990
MB
417 sst_hsw_stream_set_valid(hsw, pcm_data->stream, 32);
418 break;
419 default:
420 dev_err(rtd->dev, "error: invalid format %d\n",
421 params_format(params));
422 return -EINVAL;
423 }
424
425 ret = sst_hsw_stream_set_bits(hsw, pcm_data->stream, bits);
426 if (ret < 0) {
427 dev_err(rtd->dev, "error: could not set bits %d\n", bits);
428 return ret;
429 }
430
a4b12990 431 channels = params_channels(params);
a4b12990
MB
432 map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO);
433 sst_hsw_stream_set_map_config(hsw, pcm_data->stream,
434 map, SST_HSW_CHANNEL_CONFIG_STEREO);
435
436 ret = sst_hsw_stream_set_channels(hsw, pcm_data->stream, channels);
437 if (ret < 0) {
438 dev_err(rtd->dev, "error: could not set channels %d\n",
439 channels);
440 return ret;
441 }
442
443 ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
444 if (ret < 0) {
445 dev_err(rtd->dev, "error: could not allocate %d bytes for PCM %d\n",
446 params_buffer_bytes(params), ret);
447 return ret;
448 }
449
0b708c87
LG
450 dmab = snd_pcm_get_dma_buf(substream);
451
452 ret = create_adsp_page_table(substream, pdata, rtd, runtime->dma_area,
453 runtime->dma_bytes, rtd->cpu_dai->id);
a4b12990
MB
454 if (ret < 0)
455 return ret;
456
457 sst_hsw_stream_set_style(hsw, pcm_data->stream,
458 SST_HSW_INTERLEAVING_PER_CHANNEL);
459
460 if (runtime->dma_bytes % PAGE_SIZE)
461 pages = (runtime->dma_bytes / PAGE_SIZE) + 1;
462 else
463 pages = runtime->dma_bytes / PAGE_SIZE;
464
465 ret = sst_hsw_stream_buffer(hsw, pcm_data->stream,
0b708c87 466 pdata->dmab[rtd->cpu_dai->id][substream->stream].addr,
a4b12990 467 pages, runtime->dma_bytes, 0,
0b708c87 468 snd_sgbuf_get_addr(dmab, 0) >> PAGE_SHIFT);
a4b12990
MB
469 if (ret < 0) {
470 dev_err(rtd->dev, "error: failed to set DMA buffer %d\n", ret);
471 return ret;
472 }
473
474 dsp = sst_hsw_get_dsp(hsw);
475
476 module_data = sst_module_get_from_id(dsp, module_id);
477 if (module_data == NULL) {
478 dev_err(rtd->dev, "error: failed to get module config\n");
479 return -EINVAL;
480 }
481
e9600bc1
LG
482 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
483 pcm_data->runtime);
a4b12990
MB
484
485 ret = sst_hsw_stream_commit(hsw, pcm_data->stream);
486 if (ret < 0) {
487 dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
488 return ret;
489 }
916152c4 490 pcm_data->allocated = true;
a4b12990
MB
491
492 ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
493 if (ret < 0)
494 dev_err(rtd->dev, "error: failed to pause %d\n", ret);
495
496 return 0;
497}
498
499static int hsw_pcm_hw_free(struct snd_pcm_substream *substream)
500{
501 snd_pcm_lib_free_pages(substream);
502 return 0;
503}
504
505static int hsw_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
506{
507 struct snd_soc_pcm_runtime *rtd = substream->private_data;
508 struct hsw_priv_data *pdata =
509 snd_soc_platform_get_drvdata(rtd->platform);
510 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
511 struct sst_hsw *hsw = pdata->hsw;
512
513 switch (cmd) {
514 case SNDRV_PCM_TRIGGER_START:
515 case SNDRV_PCM_TRIGGER_RESUME:
516 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
517 sst_hsw_stream_resume(hsw, pcm_data->stream, 0);
518 break;
519 case SNDRV_PCM_TRIGGER_STOP:
520 case SNDRV_PCM_TRIGGER_SUSPEND:
521 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
522 sst_hsw_stream_pause(hsw, pcm_data->stream, 0);
523 break;
524 default:
525 break;
526 }
527
528 return 0;
529}
530
531static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
532{
533 struct hsw_pcm_data *pcm_data = data;
534 struct snd_pcm_substream *substream = pcm_data->substream;
535 struct snd_pcm_runtime *runtime = substream->runtime;
536 struct snd_soc_pcm_runtime *rtd = substream->private_data;
537 u32 pos;
538
539 pos = frames_to_bytes(runtime,
540 (runtime->control->appl_ptr % runtime->buffer_size));
541
8046249d 542 dev_vdbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
a4b12990
MB
543
544 /* let alsa know we have play a period */
545 snd_pcm_period_elapsed(substream);
546 return pos;
547}
548
549static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
550{
551 struct snd_soc_pcm_runtime *rtd = substream->private_data;
552 struct snd_pcm_runtime *runtime = substream->runtime;
553 struct hsw_priv_data *pdata =
554 snd_soc_platform_get_drvdata(rtd->platform);
555 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
556 struct sst_hsw *hsw = pdata->hsw;
557 snd_pcm_uframes_t offset;
51b4e24f
LG
558 uint64_t ppos;
559 u32 position = sst_hsw_get_dsp_position(hsw, pcm_data->stream);
a4b12990 560
51b4e24f
LG
561 offset = bytes_to_frames(runtime, position);
562 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
a4b12990 563
8046249d 564 dev_vdbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
51b4e24f 565 position, ppos);
a4b12990
MB
566 return offset;
567}
568
569static int hsw_pcm_open(struct snd_pcm_substream *substream)
570{
571 struct snd_soc_pcm_runtime *rtd = substream->private_data;
572 struct hsw_priv_data *pdata =
573 snd_soc_platform_get_drvdata(rtd->platform);
574 struct hsw_pcm_data *pcm_data;
575 struct sst_hsw *hsw = pdata->hsw;
576
577 pcm_data = &pdata->pcm[rtd->cpu_dai->id];
578
579 mutex_lock(&pcm_data->mutex);
580
581 snd_soc_pcm_set_drvdata(rtd, pcm_data);
582 pcm_data->substream = substream;
583
584 snd_soc_set_runtime_hwparams(substream, &hsw_pcm_hardware);
585
586 pcm_data->stream = sst_hsw_stream_new(hsw, rtd->cpu_dai->id,
587 hsw_notify_pointer, pcm_data);
588 if (pcm_data->stream == NULL) {
589 dev_err(rtd->dev, "error: failed to create stream\n");
590 mutex_unlock(&pcm_data->mutex);
591 return -EINVAL;
592 }
593
594 /* Set previous saved volume */
595 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
596 0, pcm_data->volume[0]);
597 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
598 1, pcm_data->volume[1]);
599
600 mutex_unlock(&pcm_data->mutex);
601 return 0;
602}
603
604static int hsw_pcm_close(struct snd_pcm_substream *substream)
605{
606 struct snd_soc_pcm_runtime *rtd = substream->private_data;
607 struct hsw_priv_data *pdata =
608 snd_soc_platform_get_drvdata(rtd->platform);
609 struct hsw_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd);
610 struct sst_hsw *hsw = pdata->hsw;
611 int ret;
612
613 mutex_lock(&pcm_data->mutex);
614 ret = sst_hsw_stream_reset(hsw, pcm_data->stream);
615 if (ret < 0) {
616 dev_dbg(rtd->dev, "error: reset stream failed %d\n", ret);
617 goto out;
618 }
619
620 ret = sst_hsw_stream_free(hsw, pcm_data->stream);
621 if (ret < 0) {
622 dev_dbg(rtd->dev, "error: free stream failed %d\n", ret);
623 goto out;
624 }
916152c4 625 pcm_data->allocated = 0;
a4b12990
MB
626 pcm_data->stream = NULL;
627
628out:
629 mutex_unlock(&pcm_data->mutex);
630 return ret;
631}
632
633static struct snd_pcm_ops hsw_pcm_ops = {
634 .open = hsw_pcm_open,
635 .close = hsw_pcm_close,
636 .ioctl = snd_pcm_lib_ioctl,
637 .hw_params = hsw_pcm_hw_params,
638 .hw_free = hsw_pcm_hw_free,
639 .trigger = hsw_pcm_trigger,
640 .pointer = hsw_pcm_pointer,
0b708c87 641 .page = snd_pcm_sgbuf_ops_page,
a4b12990
MB
642};
643
e9600bc1
LG
644/* static mappings between PCMs and modules - may be dynamic in future */
645static struct hsw_pcm_module_map mod_map[] = {
646 {0, SST_HSW_MODULE_PCM_SYSTEM}, /* "System Pin" */
647 {1, SST_HSW_MODULE_PCM}, /* "Offload0 Pin" */
648 {2, SST_HSW_MODULE_PCM}, /* "Offload1 Pin" */
649 {3, SST_HSW_MODULE_PCM_REFERENCE}, /* "Loopback Pin" */
650 {4, SST_HSW_MODULE_PCM_CAPTURE}, /* "Capture Pin" */
651};
652
653static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
654{
655 struct sst_hsw *hsw = pdata->hsw;
656 struct hsw_pcm_data *pcm_data;
657 int i;
658
659 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
660 pcm_data = &pdata->pcm[i];
661
662 pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
663 mod_map[i].mod_id, pcm_data->persistent_offset);
664 if (pcm_data->runtime == NULL)
665 goto err;
666 pcm_data->persistent_offset =
667 pcm_data->runtime->persistent_offset;
668 }
669
670 return 0;
671
672err:
673 for (--i; i >= 0; i--) {
674 pcm_data = &pdata->pcm[i];
675 sst_hsw_runtime_module_free(pcm_data->runtime);
676 }
677
678 return -ENODEV;
679}
680
681static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
682{
683 struct hsw_pcm_data *pcm_data;
684 int i;
685
686 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
687 pcm_data = &pdata->pcm[i];
688
689 sst_hsw_runtime_module_free(pcm_data->runtime);
690 }
691}
692
a4b12990
MB
693static void hsw_pcm_free(struct snd_pcm *pcm)
694{
695 snd_pcm_lib_preallocate_free_for_all(pcm);
696}
697
698static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
699{
700 struct snd_pcm *pcm = rtd->pcm;
10df3509
LG
701 struct snd_soc_platform *platform = rtd->platform;
702 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
703 struct device *dev = pdata->dma_dev;
a4b12990
MB
704 int ret = 0;
705
a4b12990
MB
706 if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream ||
707 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
708 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
0b708c87 709 SNDRV_DMA_TYPE_DEV_SG,
10df3509 710 dev,
a4b12990
MB
711 hsw_pcm_hardware.buffer_bytes_max,
712 hsw_pcm_hardware.buffer_bytes_max);
713 if (ret) {
714 dev_err(rtd->dev, "dma buffer allocation failed %d\n",
715 ret);
716 return ret;
717 }
718 }
719
720 return ret;
721}
722
723#define HSW_FORMATS \
8e897618
JY
724 (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
725 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
726 SNDRV_PCM_FMTBIT_S8)
a4b12990
MB
727
728static struct snd_soc_dai_driver hsw_dais[] = {
729 {
730 .name = "System Pin",
731 .playback = {
732 .stream_name = "System Playback",
733 .channels_min = 2,
734 .channels_max = 2,
735 .rates = SNDRV_PCM_RATE_48000,
8e897618 736 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
a4b12990
MB
737 },
738 },
739 {
740 /* PCM */
741 .name = "Offload0 Pin",
742 .playback = {
743 .stream_name = "Offload0 Playback",
744 .channels_min = 2,
745 .channels_max = 2,
746 .rates = SNDRV_PCM_RATE_8000_192000,
747 .formats = HSW_FORMATS,
748 },
749 },
750 {
751 /* PCM */
752 .name = "Offload1 Pin",
753 .playback = {
754 .stream_name = "Offload1 Playback",
755 .channels_min = 2,
756 .channels_max = 2,
757 .rates = SNDRV_PCM_RATE_8000_192000,
758 .formats = HSW_FORMATS,
759 },
760 },
761 {
762 .name = "Loopback Pin",
763 .capture = {
764 .stream_name = "Loopback Capture",
765 .channels_min = 2,
766 .channels_max = 2,
8e897618
JY
767 .rates = SNDRV_PCM_RATE_48000,
768 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
a4b12990
MB
769 },
770 },
771 {
772 .name = "Capture Pin",
773 .capture = {
774 .stream_name = "Analog Capture",
775 .channels_min = 2,
48dc326f 776 .channels_max = 4,
8e897618
JY
777 .rates = SNDRV_PCM_RATE_48000,
778 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
a4b12990
MB
779 },
780 },
781};
782
783static const struct snd_soc_dapm_widget widgets[] = {
784
785 /* Backend DAIs */
786 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL, 0, SND_SOC_NOPM, 0, 0),
787 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
788 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL, 0, SND_SOC_NOPM, 0, 0),
789 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL, 0, SND_SOC_NOPM, 0, 0),
790
791 /* Global Playback Mixer */
792 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM, 0, 0, NULL, 0),
793};
794
795static const struct snd_soc_dapm_route graph[] = {
796
797 /* Playback Mixer */
798 {"Playback VMixer", NULL, "System Playback"},
799 {"Playback VMixer", NULL, "Offload0 Playback"},
800 {"Playback VMixer", NULL, "Offload1 Playback"},
801
802 {"SSP0 CODEC OUT", NULL, "Playback VMixer"},
803
804 {"Analog Capture", NULL, "SSP0 CODEC IN"},
805};
806
807static int hsw_pcm_probe(struct snd_soc_platform *platform)
808{
bd033808 809 struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
a4b12990 810 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
bd033808 811 struct device *dma_dev = pdata->dma_dev;
0b708c87 812 int i, ret = 0;
a4b12990 813
a4b12990
MB
814 /* allocate DSP buffer page tables */
815 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
816
817 mutex_init(&priv_data->pcm[i].mutex);
818
819 /* playback */
820 if (hsw_dais[i].playback.channels_min) {
0b708c87
LG
821 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
822 PAGE_SIZE, &priv_data->dmab[i][0]);
823 if (ret < 0)
a4b12990
MB
824 goto err;
825 }
826
827 /* capture */
828 if (hsw_dais[i].capture.channels_min) {
0b708c87
LG
829 ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dma_dev,
830 PAGE_SIZE, &priv_data->dmab[i][1]);
831 if (ret < 0)
a4b12990
MB
832 goto err;
833 }
834 }
835
e9600bc1
LG
836 /* allocate runtime modules */
837 hsw_pcm_create_modules(priv_data);
838
a4b12990
MB
839 return 0;
840
841err:
842 for (;i >= 0; i--) {
843 if (hsw_dais[i].playback.channels_min)
0b708c87 844 snd_dma_free_pages(&priv_data->dmab[i][0]);
a4b12990 845 if (hsw_dais[i].capture.channels_min)
0b708c87 846 snd_dma_free_pages(&priv_data->dmab[i][1]);
a4b12990 847 }
0b708c87 848 return ret;
a4b12990
MB
849}
850
851static int hsw_pcm_remove(struct snd_soc_platform *platform)
852{
853 struct hsw_priv_data *priv_data =
854 snd_soc_platform_get_drvdata(platform);
855 int i;
856
857 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
858 if (hsw_dais[i].playback.channels_min)
0b708c87 859 snd_dma_free_pages(&priv_data->dmab[i][0]);
a4b12990 860 if (hsw_dais[i].capture.channels_min)
0b708c87 861 snd_dma_free_pages(&priv_data->dmab[i][1]);
a4b12990
MB
862 }
863
864 return 0;
865}
866
867static struct snd_soc_platform_driver hsw_soc_platform = {
868 .probe = hsw_pcm_probe,
869 .remove = hsw_pcm_remove,
870 .ops = &hsw_pcm_ops,
871 .pcm_new = hsw_pcm_new,
872 .pcm_free = hsw_pcm_free,
a4b12990
MB
873};
874
875static const struct snd_soc_component_driver hsw_dai_component = {
923976a3
LPC
876 .name = "haswell-dai",
877 .controls = hsw_volume_controls,
878 .num_controls = ARRAY_SIZE(hsw_volume_controls),
879 .dapm_widgets = widgets,
880 .num_dapm_widgets = ARRAY_SIZE(widgets),
881 .dapm_routes = graph,
882 .num_dapm_routes = ARRAY_SIZE(graph),
a4b12990
MB
883};
884
885static int hsw_pcm_dev_probe(struct platform_device *pdev)
886{
887 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
bd033808 888 struct hsw_priv_data *priv_data;
a4b12990
MB
889 int ret;
890
bd033808
LPC
891 if (!sst_pdata)
892 return -EINVAL;
893
894 priv_data = devm_kzalloc(&pdev->dev, sizeof(*priv_data), GFP_KERNEL);
895 if (!priv_data)
896 return -ENOMEM;
897
a4b12990
MB
898 ret = sst_hsw_dsp_init(&pdev->dev, sst_pdata);
899 if (ret < 0)
900 return -ENODEV;
901
bd033808
LPC
902 priv_data->hsw = sst_pdata->dsp;
903 platform_set_drvdata(pdev, priv_data);
904
a4b12990
MB
905 ret = snd_soc_register_platform(&pdev->dev, &hsw_soc_platform);
906 if (ret < 0)
907 goto err_plat;
908
909 ret = snd_soc_register_component(&pdev->dev, &hsw_dai_component,
910 hsw_dais, ARRAY_SIZE(hsw_dais));
911 if (ret < 0)
912 goto err_comp;
913
914 return 0;
915
916err_comp:
917 snd_soc_unregister_platform(&pdev->dev);
918err_plat:
919 sst_hsw_dsp_free(&pdev->dev, sst_pdata);
920 return 0;
921}
922
923static int hsw_pcm_dev_remove(struct platform_device *pdev)
924{
925 struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev);
926
927 snd_soc_unregister_platform(&pdev->dev);
928 snd_soc_unregister_component(&pdev->dev);
929 sst_hsw_dsp_free(&pdev->dev, sst_pdata);
930
931 return 0;
932}
933
934static struct platform_driver hsw_pcm_driver = {
935 .driver = {
936 .name = "haswell-pcm-audio",
937 .owner = THIS_MODULE,
938 },
939
940 .probe = hsw_pcm_dev_probe,
941 .remove = hsw_pcm_dev_remove,
942};
943module_platform_driver(hsw_pcm_driver);
944
945MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
946MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
947MODULE_LICENSE("GPL v2");
948MODULE_ALIAS("platform:haswell-pcm-audio");
This page took 0.10833 seconds and 5 git commands to generate.