2 * Intel SST Haswell/Broadwell PCM Support
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
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.
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.
17 #include <linux/module.h>
18 #include <linux/dma-mapping.h>
19 #include <linux/slab.h>
20 #include <linux/delay.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>
31 #include "sst-haswell-ipc.h"
32 #include "sst-dsp-priv.h"
35 #define HSW_PCM_COUNT 6
36 #define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
38 /* simple volume table */
39 static const u32 volume_map
[] = {
73 #define HSW_PCM_PERIODS_MAX 64
74 #define HSW_PCM_PERIODS_MIN 2
76 static 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
,
83 .formats
= SNDRV_PCM_FMTBIT_S16_LE
| SNDRV_PCM_FMTBIT_S24_LE
|
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
,
92 /* private data for each PCM DSP stream */
95 struct sst_hsw_stream
*stream
;
97 struct snd_pcm_substream
*substream
;
98 struct snd_compr_stream
*cstream
;
104 /* private data for the driver */
105 struct hsw_priv_data
{
110 struct snd_dma_buffer dmab
[HSW_PCM_COUNT
][2];
113 struct hsw_pcm_data pcm
[HSW_PCM_COUNT
];
116 static u32
hsw_notify_pointer(struct sst_hsw_stream
*stream
, void *data
);
118 static inline u32
hsw_mixer_to_ipc(unsigned int value
)
120 if (value
>= ARRAY_SIZE(volume_map
))
121 return volume_map
[0];
123 return volume_map
[value
];
126 static inline unsigned int hsw_ipc_to_mixer(u32 value
)
130 for (i
= 0; i
< ARRAY_SIZE(volume_map
); i
++) {
131 if (volume_map
[i
] >= value
)
138 static int hsw_stream_volume_put(struct snd_kcontrol
*kcontrol
,
139 struct snd_ctl_elem_value
*ucontrol
)
141 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
142 struct hsw_priv_data
*pdata
= snd_soc_component_get_drvdata(cmpnt
);
143 struct soc_mixer_control
*mc
=
144 (struct soc_mixer_control
*)kcontrol
->private_value
;
145 struct hsw_pcm_data
*pcm_data
= &pdata
->pcm
[mc
->reg
];
146 struct sst_hsw
*hsw
= pdata
->hsw
;
149 mutex_lock(&pcm_data
->mutex
);
151 if (!pcm_data
->stream
) {
152 pcm_data
->volume
[0] =
153 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
154 pcm_data
->volume
[1] =
155 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
156 mutex_unlock(&pcm_data
->mutex
);
160 if (ucontrol
->value
.integer
.value
[0] ==
161 ucontrol
->value
.integer
.value
[1]) {
162 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
163 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 2, volume
);
165 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
166 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 0, volume
);
167 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
168 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 1, volume
);
171 mutex_unlock(&pcm_data
->mutex
);
175 static int hsw_stream_volume_get(struct snd_kcontrol
*kcontrol
,
176 struct snd_ctl_elem_value
*ucontrol
)
178 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
179 struct hsw_priv_data
*pdata
= snd_soc_component_get_drvdata(cmpnt
);
180 struct soc_mixer_control
*mc
=
181 (struct soc_mixer_control
*)kcontrol
->private_value
;
182 struct hsw_pcm_data
*pcm_data
= &pdata
->pcm
[mc
->reg
];
183 struct sst_hsw
*hsw
= pdata
->hsw
;
186 mutex_lock(&pcm_data
->mutex
);
188 if (!pcm_data
->stream
) {
189 ucontrol
->value
.integer
.value
[0] =
190 hsw_ipc_to_mixer(pcm_data
->volume
[0]);
191 ucontrol
->value
.integer
.value
[1] =
192 hsw_ipc_to_mixer(pcm_data
->volume
[1]);
193 mutex_unlock(&pcm_data
->mutex
);
197 sst_hsw_stream_get_volume(hsw
, pcm_data
->stream
, 0, 0, &volume
);
198 ucontrol
->value
.integer
.value
[0] = hsw_ipc_to_mixer(volume
);
199 sst_hsw_stream_get_volume(hsw
, pcm_data
->stream
, 0, 1, &volume
);
200 ucontrol
->value
.integer
.value
[1] = hsw_ipc_to_mixer(volume
);
201 mutex_unlock(&pcm_data
->mutex
);
206 static int hsw_volume_put(struct snd_kcontrol
*kcontrol
,
207 struct snd_ctl_elem_value
*ucontrol
)
209 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
210 struct hsw_priv_data
*pdata
= snd_soc_component_get_drvdata(cmpnt
);
211 struct sst_hsw
*hsw
= pdata
->hsw
;
214 if (ucontrol
->value
.integer
.value
[0] ==
215 ucontrol
->value
.integer
.value
[1]) {
217 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
218 sst_hsw_mixer_set_volume(hsw
, 0, 2, volume
);
221 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
222 sst_hsw_mixer_set_volume(hsw
, 0, 0, volume
);
224 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
225 sst_hsw_mixer_set_volume(hsw
, 0, 1, volume
);
231 static int hsw_volume_get(struct snd_kcontrol
*kcontrol
,
232 struct snd_ctl_elem_value
*ucontrol
)
234 struct snd_soc_component
*cmpnt
= snd_soc_kcontrol_component(kcontrol
);
235 struct hsw_priv_data
*pdata
= snd_soc_component_get_drvdata(cmpnt
);
236 struct sst_hsw
*hsw
= pdata
->hsw
;
237 unsigned int volume
= 0;
239 sst_hsw_mixer_get_volume(hsw
, 0, 0, &volume
);
240 ucontrol
->value
.integer
.value
[0] = hsw_ipc_to_mixer(volume
);
242 sst_hsw_mixer_get_volume(hsw
, 0, 1, &volume
);
243 ucontrol
->value
.integer
.value
[1] = hsw_ipc_to_mixer(volume
);
248 /* TLV used by both global and stream volumes */
249 static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv
, -9000, 300, 1);
251 /* System Pin has no volume control */
252 static const struct snd_kcontrol_new hsw_volume_controls
[] = {
253 /* Global DSP volume */
254 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
255 ARRAY_SIZE(volume_map
) -1, 0,
256 hsw_volume_get
, hsw_volume_put
, hsw_vol_tlv
),
257 /* Offload 0 volume */
258 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
259 ARRAY_SIZE(volume_map
), 0,
260 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
261 /* Offload 1 volume */
262 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
263 ARRAY_SIZE(volume_map
), 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
),
269 /* Mic Capture volume */
270 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
271 ARRAY_SIZE(volume_map
), 0,
272 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
275 /* Create DMA buffer page table for DSP */
276 static int create_adsp_page_table(struct snd_pcm_substream
*substream
,
277 struct hsw_priv_data
*pdata
, struct snd_soc_pcm_runtime
*rtd
,
278 unsigned char *dma_area
, size_t size
, int pcm
)
280 struct snd_dma_buffer
*dmab
= snd_pcm_get_dma_buf(substream
);
281 int i
, pages
, stream
= substream
->stream
;
283 pages
= snd_sgbuf_aligned_pages(size
);
285 dev_dbg(rtd
->dev
, "generating page table for %p size 0x%zu pages %d\n",
286 dma_area
, size
, pages
);
288 for (i
= 0; i
< pages
; i
++) {
289 u32 idx
= (((i
<< 2) + i
)) >> 1;
290 u32 pfn
= snd_sgbuf_get_addr(dmab
, i
* PAGE_SIZE
) >> PAGE_SHIFT
;
293 dev_dbg(rtd
->dev
, "pfn i %i idx %d pfn %x\n", i
, idx
, pfn
);
295 pg_table
= (u32
*)(pdata
->dmab
[pcm
][stream
].area
+ idx
);
298 *pg_table
|= (pfn
<< 4);
306 /* this may get called several times by oss emulation */
307 static int hsw_pcm_hw_params(struct snd_pcm_substream
*substream
,
308 struct snd_pcm_hw_params
*params
)
310 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
311 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
312 struct hsw_priv_data
*pdata
=
313 snd_soc_platform_get_drvdata(rtd
->platform
);
314 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
315 struct sst_hsw
*hsw
= pdata
->hsw
;
316 struct sst_module
*module_data
;
318 struct snd_dma_buffer
*dmab
;
319 enum sst_hsw_stream_type stream_type
;
320 enum sst_hsw_stream_path_id path_id
;
321 u32 rate
, bits
, map
, pages
, module_id
;
325 /* check if we are being called a subsequent time */
326 if (pcm_data
->allocated
) {
327 ret
= sst_hsw_stream_reset(hsw
, pcm_data
->stream
);
329 dev_dbg(rtd
->dev
, "error: reset stream failed %d\n",
332 ret
= sst_hsw_stream_free(hsw
, pcm_data
->stream
);
334 dev_dbg(rtd
->dev
, "error: free stream failed %d\n",
338 pcm_data
->allocated
= false;
340 pcm_data
->stream
= sst_hsw_stream_new(hsw
, rtd
->cpu_dai
->id
,
341 hsw_notify_pointer
, pcm_data
);
342 if (pcm_data
->stream
== NULL
) {
343 dev_err(rtd
->dev
, "error: failed to create stream\n");
348 /* stream direction */
349 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
350 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
352 path_id
= SST_HSW_STREAM_PATH_SSP0_IN
;
354 /* DSP stream type depends on DAI ID */
355 switch (rtd
->cpu_dai
->id
) {
357 stream_type
= SST_HSW_STREAM_TYPE_SYSTEM
;
358 module_id
= SST_HSW_MODULE_PCM_SYSTEM
;
362 stream_type
= SST_HSW_STREAM_TYPE_RENDER
;
363 module_id
= SST_HSW_MODULE_PCM
;
366 /* path ID needs to be OUT for loopback */
367 stream_type
= SST_HSW_STREAM_TYPE_LOOPBACK
;
368 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
369 module_id
= SST_HSW_MODULE_PCM_REFERENCE
;
372 stream_type
= SST_HSW_STREAM_TYPE_CAPTURE
;
373 module_id
= SST_HSW_MODULE_PCM_CAPTURE
;
376 dev_err(rtd
->dev
, "error: invalid DAI ID %d\n",
381 ret
= sst_hsw_stream_format(hsw
, pcm_data
->stream
,
382 path_id
, stream_type
, SST_HSW_STREAM_FORMAT_PCM_FORMAT
);
384 dev_err(rtd
->dev
, "error: failed to set format %d\n", ret
);
388 rate
= params_rate(params
);
389 ret
= sst_hsw_stream_set_rate(hsw
, pcm_data
->stream
, rate
);
391 dev_err(rtd
->dev
, "error: could not set rate %d\n", rate
);
395 switch (params_format(params
)) {
396 case SNDRV_PCM_FORMAT_S16_LE
:
397 bits
= SST_HSW_DEPTH_16BIT
;
398 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 16);
400 case SNDRV_PCM_FORMAT_S24_LE
:
401 bits
= SST_HSW_DEPTH_32BIT
;
402 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 24);
404 case SNDRV_PCM_FORMAT_S8
:
405 bits
= SST_HSW_DEPTH_8BIT
;
406 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 8);
408 case SNDRV_PCM_FORMAT_S32_LE
:
409 bits
= SST_HSW_DEPTH_32BIT
;
410 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 32);
413 dev_err(rtd
->dev
, "error: invalid format %d\n",
414 params_format(params
));
418 ret
= sst_hsw_stream_set_bits(hsw
, pcm_data
->stream
, bits
);
420 dev_err(rtd
->dev
, "error: could not set bits %d\n", bits
);
424 /* we only support stereo atm */
425 channels
= params_channels(params
);
427 dev_err(rtd
->dev
, "error: invalid channels %d\n", channels
);
431 map
= create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO
);
432 sst_hsw_stream_set_map_config(hsw
, pcm_data
->stream
,
433 map
, SST_HSW_CHANNEL_CONFIG_STEREO
);
435 ret
= sst_hsw_stream_set_channels(hsw
, pcm_data
->stream
, channels
);
437 dev_err(rtd
->dev
, "error: could not set channels %d\n",
442 ret
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(params
));
444 dev_err(rtd
->dev
, "error: could not allocate %d bytes for PCM %d\n",
445 params_buffer_bytes(params
), ret
);
449 dmab
= snd_pcm_get_dma_buf(substream
);
451 ret
= create_adsp_page_table(substream
, pdata
, rtd
, runtime
->dma_area
,
452 runtime
->dma_bytes
, rtd
->cpu_dai
->id
);
456 sst_hsw_stream_set_style(hsw
, pcm_data
->stream
,
457 SST_HSW_INTERLEAVING_PER_CHANNEL
);
459 if (runtime
->dma_bytes
% PAGE_SIZE
)
460 pages
= (runtime
->dma_bytes
/ PAGE_SIZE
) + 1;
462 pages
= runtime
->dma_bytes
/ PAGE_SIZE
;
464 ret
= sst_hsw_stream_buffer(hsw
, pcm_data
->stream
,
465 pdata
->dmab
[rtd
->cpu_dai
->id
][substream
->stream
].addr
,
466 pages
, runtime
->dma_bytes
, 0,
467 snd_sgbuf_get_addr(dmab
, 0) >> PAGE_SHIFT
);
469 dev_err(rtd
->dev
, "error: failed to set DMA buffer %d\n", ret
);
473 dsp
= sst_hsw_get_dsp(hsw
);
475 module_data
= sst_module_get_from_id(dsp
, module_id
);
476 if (module_data
== NULL
) {
477 dev_err(rtd
->dev
, "error: failed to get module config\n");
481 /* we use hardcoded memory offsets atm, will be updated for new FW */
482 if (stream_type
== SST_HSW_STREAM_TYPE_CAPTURE
) {
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
,
487 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
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
);
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
,
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
,
504 ret
= sst_hsw_stream_commit(hsw
, pcm_data
->stream
);
506 dev_err(rtd
->dev
, "error: failed to commit stream %d\n", ret
);
509 pcm_data
->allocated
= true;
511 ret
= sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 1);
513 dev_err(rtd
->dev
, "error: failed to pause %d\n", ret
);
518 static int hsw_pcm_hw_free(struct snd_pcm_substream
*substream
)
520 snd_pcm_lib_free_pages(substream
);
524 static int hsw_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
526 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
527 struct hsw_priv_data
*pdata
=
528 snd_soc_platform_get_drvdata(rtd
->platform
);
529 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
530 struct sst_hsw
*hsw
= pdata
->hsw
;
533 case SNDRV_PCM_TRIGGER_START
:
534 case SNDRV_PCM_TRIGGER_RESUME
:
535 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
536 sst_hsw_stream_resume(hsw
, pcm_data
->stream
, 0);
538 case SNDRV_PCM_TRIGGER_STOP
:
539 case SNDRV_PCM_TRIGGER_SUSPEND
:
540 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
541 sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 0);
550 static u32
hsw_notify_pointer(struct sst_hsw_stream
*stream
, void *data
)
552 struct hsw_pcm_data
*pcm_data
= data
;
553 struct snd_pcm_substream
*substream
= pcm_data
->substream
;
554 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
555 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
558 pos
= frames_to_bytes(runtime
,
559 (runtime
->control
->appl_ptr
% runtime
->buffer_size
));
561 dev_dbg(rtd
->dev
, "PCM: App pointer %d bytes\n", pos
);
563 /* let alsa know we have play a period */
564 snd_pcm_period_elapsed(substream
);
568 static snd_pcm_uframes_t
hsw_pcm_pointer(struct snd_pcm_substream
*substream
)
570 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
571 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
572 struct hsw_priv_data
*pdata
=
573 snd_soc_platform_get_drvdata(rtd
->platform
);
574 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
575 struct sst_hsw
*hsw
= pdata
->hsw
;
576 snd_pcm_uframes_t offset
;
578 u32 position
= sst_hsw_get_dsp_position(hsw
, pcm_data
->stream
);
580 offset
= bytes_to_frames(runtime
, position
);
581 ppos
= sst_hsw_get_dsp_presentation_position(hsw
, pcm_data
->stream
);
583 dev_dbg(rtd
->dev
, "PCM: DMA pointer %du bytes, pos %llu\n",
588 static int hsw_pcm_open(struct snd_pcm_substream
*substream
)
590 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
591 struct hsw_priv_data
*pdata
=
592 snd_soc_platform_get_drvdata(rtd
->platform
);
593 struct hsw_pcm_data
*pcm_data
;
594 struct sst_hsw
*hsw
= pdata
->hsw
;
596 pcm_data
= &pdata
->pcm
[rtd
->cpu_dai
->id
];
598 mutex_lock(&pcm_data
->mutex
);
600 snd_soc_pcm_set_drvdata(rtd
, pcm_data
);
601 pcm_data
->substream
= substream
;
603 snd_soc_set_runtime_hwparams(substream
, &hsw_pcm_hardware
);
605 pcm_data
->stream
= sst_hsw_stream_new(hsw
, rtd
->cpu_dai
->id
,
606 hsw_notify_pointer
, pcm_data
);
607 if (pcm_data
->stream
== NULL
) {
608 dev_err(rtd
->dev
, "error: failed to create stream\n");
609 mutex_unlock(&pcm_data
->mutex
);
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]);
619 mutex_unlock(&pcm_data
->mutex
);
623 static int hsw_pcm_close(struct snd_pcm_substream
*substream
)
625 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
626 struct hsw_priv_data
*pdata
=
627 snd_soc_platform_get_drvdata(rtd
->platform
);
628 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
629 struct sst_hsw
*hsw
= pdata
->hsw
;
632 mutex_lock(&pcm_data
->mutex
);
633 ret
= sst_hsw_stream_reset(hsw
, pcm_data
->stream
);
635 dev_dbg(rtd
->dev
, "error: reset stream failed %d\n", ret
);
639 ret
= sst_hsw_stream_free(hsw
, pcm_data
->stream
);
641 dev_dbg(rtd
->dev
, "error: free stream failed %d\n", ret
);
644 pcm_data
->allocated
= 0;
645 pcm_data
->stream
= NULL
;
648 mutex_unlock(&pcm_data
->mutex
);
652 static struct snd_pcm_ops hsw_pcm_ops
= {
653 .open
= hsw_pcm_open
,
654 .close
= hsw_pcm_close
,
655 .ioctl
= snd_pcm_lib_ioctl
,
656 .hw_params
= hsw_pcm_hw_params
,
657 .hw_free
= hsw_pcm_hw_free
,
658 .trigger
= hsw_pcm_trigger
,
659 .pointer
= hsw_pcm_pointer
,
660 .page
= snd_pcm_sgbuf_ops_page
,
663 static void hsw_pcm_free(struct snd_pcm
*pcm
)
665 snd_pcm_lib_preallocate_free_for_all(pcm
);
668 static int hsw_pcm_new(struct snd_soc_pcm_runtime
*rtd
)
670 struct snd_pcm
*pcm
= rtd
->pcm
;
671 struct snd_soc_platform
*platform
= rtd
->platform
;
672 struct sst_pdata
*pdata
= dev_get_platdata(platform
->dev
);
673 struct device
*dev
= pdata
->dma_dev
;
676 if (pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
||
677 pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
) {
678 ret
= snd_pcm_lib_preallocate_pages_for_all(pcm
,
679 SNDRV_DMA_TYPE_DEV_SG
,
681 hsw_pcm_hardware
.buffer_bytes_max
,
682 hsw_pcm_hardware
.buffer_bytes_max
);
684 dev_err(rtd
->dev
, "dma buffer allocation failed %d\n",
693 #define HSW_FORMATS \
694 (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
696 static struct snd_soc_dai_driver hsw_dais
[] = {
698 .name
= "System Pin",
700 .stream_name
= "System Playback",
703 .rates
= SNDRV_PCM_RATE_48000
,
704 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
709 .name
= "Offload0 Pin",
711 .stream_name
= "Offload0 Playback",
714 .rates
= SNDRV_PCM_RATE_8000_192000
,
715 .formats
= HSW_FORMATS
,
720 .name
= "Offload1 Pin",
722 .stream_name
= "Offload1 Playback",
725 .rates
= SNDRV_PCM_RATE_8000_192000
,
726 .formats
= HSW_FORMATS
,
730 .name
= "Loopback Pin",
732 .stream_name
= "Loopback Capture",
735 .rates
= SNDRV_PCM_RATE_48000
,
736 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
740 .name
= "Capture Pin",
742 .stream_name
= "Analog Capture",
745 .rates
= SNDRV_PCM_RATE_48000
,
746 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
751 static const struct snd_soc_dapm_widget widgets
[] = {
754 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
755 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
756 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
757 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
759 /* Global Playback Mixer */
760 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM
, 0, 0, NULL
, 0),
763 static const struct snd_soc_dapm_route graph
[] = {
766 {"Playback VMixer", NULL
, "System Playback"},
767 {"Playback VMixer", NULL
, "Offload0 Playback"},
768 {"Playback VMixer", NULL
, "Offload1 Playback"},
770 {"SSP0 CODEC OUT", NULL
, "Playback VMixer"},
772 {"Analog Capture", NULL
, "SSP0 CODEC IN"},
775 static int hsw_pcm_probe(struct snd_soc_platform
*platform
)
777 struct hsw_priv_data
*priv_data
= snd_soc_platform_get_drvdata(platform
);
778 struct sst_pdata
*pdata
= dev_get_platdata(platform
->dev
);
779 struct device
*dma_dev
= pdata
->dma_dev
;
782 /* allocate DSP buffer page tables */
783 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
785 mutex_init(&priv_data
->pcm
[i
].mutex
);
788 if (hsw_dais
[i
].playback
.channels_min
) {
789 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
790 PAGE_SIZE
, &priv_data
->dmab
[i
][0]);
796 if (hsw_dais
[i
].capture
.channels_min
) {
797 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
798 PAGE_SIZE
, &priv_data
->dmab
[i
][1]);
808 if (hsw_dais
[i
].playback
.channels_min
)
809 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
810 if (hsw_dais
[i
].capture
.channels_min
)
811 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
816 static int hsw_pcm_remove(struct snd_soc_platform
*platform
)
818 struct hsw_priv_data
*priv_data
=
819 snd_soc_platform_get_drvdata(platform
);
822 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
823 if (hsw_dais
[i
].playback
.channels_min
)
824 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
825 if (hsw_dais
[i
].capture
.channels_min
)
826 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
832 static struct snd_soc_platform_driver hsw_soc_platform
= {
833 .probe
= hsw_pcm_probe
,
834 .remove
= hsw_pcm_remove
,
836 .pcm_new
= hsw_pcm_new
,
837 .pcm_free
= hsw_pcm_free
,
840 static const struct snd_soc_component_driver hsw_dai_component
= {
841 .name
= "haswell-dai",
842 .controls
= hsw_volume_controls
,
843 .num_controls
= ARRAY_SIZE(hsw_volume_controls
),
844 .dapm_widgets
= widgets
,
845 .num_dapm_widgets
= ARRAY_SIZE(widgets
),
846 .dapm_routes
= graph
,
847 .num_dapm_routes
= ARRAY_SIZE(graph
),
850 static int hsw_pcm_dev_probe(struct platform_device
*pdev
)
852 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
853 struct hsw_priv_data
*priv_data
;
859 priv_data
= devm_kzalloc(&pdev
->dev
, sizeof(*priv_data
), GFP_KERNEL
);
863 ret
= sst_hsw_dsp_init(&pdev
->dev
, sst_pdata
);
867 priv_data
->hsw
= sst_pdata
->dsp
;
868 platform_set_drvdata(pdev
, priv_data
);
870 ret
= snd_soc_register_platform(&pdev
->dev
, &hsw_soc_platform
);
874 ret
= snd_soc_register_component(&pdev
->dev
, &hsw_dai_component
,
875 hsw_dais
, ARRAY_SIZE(hsw_dais
));
882 snd_soc_unregister_platform(&pdev
->dev
);
884 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
888 static int hsw_pcm_dev_remove(struct platform_device
*pdev
)
890 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
892 snd_soc_unregister_platform(&pdev
->dev
);
893 snd_soc_unregister_component(&pdev
->dev
);
894 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
899 static struct platform_driver hsw_pcm_driver
= {
901 .name
= "haswell-pcm-audio",
902 .owner
= THIS_MODULE
,
905 .probe
= hsw_pcm_dev_probe
,
906 .remove
= hsw_pcm_dev_remove
,
908 module_platform_driver(hsw_pcm_driver
);
910 MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
911 MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
912 MODULE_LICENSE("GPL v2");
913 MODULE_ALIAS("platform:haswell-pcm-audio");