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_platform
*platform
= snd_soc_kcontrol_platform(kcontrol
);
142 struct soc_mixer_control
*mc
=
143 (struct soc_mixer_control
*)kcontrol
->private_value
;
144 struct hsw_priv_data
*pdata
=
145 snd_soc_platform_get_drvdata(platform
);
146 struct hsw_pcm_data
*pcm_data
= &pdata
->pcm
[mc
->reg
];
147 struct sst_hsw
*hsw
= pdata
->hsw
;
150 mutex_lock(&pcm_data
->mutex
);
152 if (!pcm_data
->stream
) {
153 pcm_data
->volume
[0] =
154 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
155 pcm_data
->volume
[1] =
156 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
157 mutex_unlock(&pcm_data
->mutex
);
161 if (ucontrol
->value
.integer
.value
[0] ==
162 ucontrol
->value
.integer
.value
[1]) {
163 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
164 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 2, volume
);
166 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
167 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 0, volume
);
168 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
169 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 1, volume
);
172 mutex_unlock(&pcm_data
->mutex
);
176 static int hsw_stream_volume_get(struct snd_kcontrol
*kcontrol
,
177 struct snd_ctl_elem_value
*ucontrol
)
179 struct snd_soc_platform
*platform
= snd_soc_kcontrol_platform(kcontrol
);
180 struct soc_mixer_control
*mc
=
181 (struct soc_mixer_control
*)kcontrol
->private_value
;
182 struct hsw_priv_data
*pdata
=
183 snd_soc_platform_get_drvdata(platform
);
184 struct hsw_pcm_data
*pcm_data
= &pdata
->pcm
[mc
->reg
];
185 struct sst_hsw
*hsw
= pdata
->hsw
;
188 mutex_lock(&pcm_data
->mutex
);
190 if (!pcm_data
->stream
) {
191 ucontrol
->value
.integer
.value
[0] =
192 hsw_ipc_to_mixer(pcm_data
->volume
[0]);
193 ucontrol
->value
.integer
.value
[1] =
194 hsw_ipc_to_mixer(pcm_data
->volume
[1]);
195 mutex_unlock(&pcm_data
->mutex
);
199 sst_hsw_stream_get_volume(hsw
, pcm_data
->stream
, 0, 0, &volume
);
200 ucontrol
->value
.integer
.value
[0] = hsw_ipc_to_mixer(volume
);
201 sst_hsw_stream_get_volume(hsw
, pcm_data
->stream
, 0, 1, &volume
);
202 ucontrol
->value
.integer
.value
[1] = hsw_ipc_to_mixer(volume
);
203 mutex_unlock(&pcm_data
->mutex
);
208 static int hsw_volume_put(struct snd_kcontrol
*kcontrol
,
209 struct snd_ctl_elem_value
*ucontrol
)
211 struct snd_soc_platform
*platform
= snd_soc_kcontrol_platform(kcontrol
);
212 struct hsw_priv_data
*pdata
= snd_soc_platform_get_drvdata(platform
);
213 struct sst_hsw
*hsw
= pdata
->hsw
;
216 if (ucontrol
->value
.integer
.value
[0] ==
217 ucontrol
->value
.integer
.value
[1]) {
219 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
220 sst_hsw_mixer_set_volume(hsw
, 0, 2, volume
);
223 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
224 sst_hsw_mixer_set_volume(hsw
, 0, 0, volume
);
226 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
227 sst_hsw_mixer_set_volume(hsw
, 0, 1, volume
);
233 static int hsw_volume_get(struct snd_kcontrol
*kcontrol
,
234 struct snd_ctl_elem_value
*ucontrol
)
236 struct snd_soc_platform
*platform
= snd_soc_kcontrol_platform(kcontrol
);
237 struct hsw_priv_data
*pdata
= snd_soc_platform_get_drvdata(platform
);
238 struct sst_hsw
*hsw
= pdata
->hsw
;
239 unsigned int volume
= 0;
241 sst_hsw_mixer_get_volume(hsw
, 0, 0, &volume
);
242 ucontrol
->value
.integer
.value
[0] = hsw_ipc_to_mixer(volume
);
244 sst_hsw_mixer_get_volume(hsw
, 0, 1, &volume
);
245 ucontrol
->value
.integer
.value
[1] = hsw_ipc_to_mixer(volume
);
250 /* TLV used by both global and stream volumes */
251 static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv
, -9000, 300, 1);
253 /* System Pin has no volume control */
254 static const struct snd_kcontrol_new hsw_volume_controls
[] = {
255 /* Global DSP volume */
256 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
257 ARRAY_SIZE(volume_map
) -1, 0,
258 hsw_volume_get
, hsw_volume_put
, hsw_vol_tlv
),
259 /* Offload 0 volume */
260 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
261 ARRAY_SIZE(volume_map
), 0,
262 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
263 /* Offload 1 volume */
264 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
265 ARRAY_SIZE(volume_map
), 0,
266 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
267 /* Loopback volume */
268 SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8,
269 ARRAY_SIZE(volume_map
), 0,
270 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
271 /* Mic Capture volume */
272 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8,
273 ARRAY_SIZE(volume_map
), 0,
274 hsw_stream_volume_get
, hsw_stream_volume_put
, hsw_vol_tlv
),
277 /* Create DMA buffer page table for DSP */
278 static int create_adsp_page_table(struct snd_pcm_substream
*substream
,
279 struct hsw_priv_data
*pdata
, struct snd_soc_pcm_runtime
*rtd
,
280 unsigned char *dma_area
, size_t size
, int pcm
)
282 struct snd_dma_buffer
*dmab
= snd_pcm_get_dma_buf(substream
);
283 int i
, pages
, stream
= substream
->stream
;
285 pages
= snd_sgbuf_aligned_pages(size
);
287 dev_dbg(rtd
->dev
, "generating page table for %p size 0x%zu pages %d\n",
288 dma_area
, size
, pages
);
290 for (i
= 0; i
< pages
; i
++) {
291 u32 idx
= (((i
<< 2) + i
)) >> 1;
292 u32 pfn
= snd_sgbuf_get_addr(dmab
, i
* PAGE_SIZE
) >> PAGE_SHIFT
;
295 dev_dbg(rtd
->dev
, "pfn i %i idx %d pfn %x\n", i
, idx
, pfn
);
297 pg_table
= (u32
*)(pdata
->dmab
[pcm
][stream
].area
+ idx
);
300 *pg_table
|= (pfn
<< 4);
308 /* this may get called several times by oss emulation */
309 static int hsw_pcm_hw_params(struct snd_pcm_substream
*substream
,
310 struct snd_pcm_hw_params
*params
)
312 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
313 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
314 struct hsw_priv_data
*pdata
=
315 snd_soc_platform_get_drvdata(rtd
->platform
);
316 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
317 struct sst_hsw
*hsw
= pdata
->hsw
;
318 struct sst_module
*module_data
;
320 struct snd_dma_buffer
*dmab
;
321 enum sst_hsw_stream_type stream_type
;
322 enum sst_hsw_stream_path_id path_id
;
323 u32 rate
, bits
, map
, pages
, module_id
;
327 /* check if we are being called a subsequent time */
328 if (pcm_data
->allocated
) {
329 ret
= sst_hsw_stream_reset(hsw
, pcm_data
->stream
);
331 dev_dbg(rtd
->dev
, "error: reset stream failed %d\n",
334 ret
= sst_hsw_stream_free(hsw
, pcm_data
->stream
);
336 dev_dbg(rtd
->dev
, "error: free stream failed %d\n",
340 pcm_data
->allocated
= false;
342 pcm_data
->stream
= sst_hsw_stream_new(hsw
, rtd
->cpu_dai
->id
,
343 hsw_notify_pointer
, pcm_data
);
344 if (pcm_data
->stream
== NULL
) {
345 dev_err(rtd
->dev
, "error: failed to create stream\n");
350 /* stream direction */
351 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
352 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
354 path_id
= SST_HSW_STREAM_PATH_SSP0_IN
;
356 /* DSP stream type depends on DAI ID */
357 switch (rtd
->cpu_dai
->id
) {
359 stream_type
= SST_HSW_STREAM_TYPE_SYSTEM
;
360 module_id
= SST_HSW_MODULE_PCM_SYSTEM
;
364 stream_type
= SST_HSW_STREAM_TYPE_RENDER
;
365 module_id
= SST_HSW_MODULE_PCM
;
368 /* path ID needs to be OUT for loopback */
369 stream_type
= SST_HSW_STREAM_TYPE_LOOPBACK
;
370 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
371 module_id
= SST_HSW_MODULE_PCM_REFERENCE
;
374 stream_type
= SST_HSW_STREAM_TYPE_CAPTURE
;
375 module_id
= SST_HSW_MODULE_PCM_CAPTURE
;
378 dev_err(rtd
->dev
, "error: invalid DAI ID %d\n",
383 ret
= sst_hsw_stream_format(hsw
, pcm_data
->stream
,
384 path_id
, stream_type
, SST_HSW_STREAM_FORMAT_PCM_FORMAT
);
386 dev_err(rtd
->dev
, "error: failed to set format %d\n", ret
);
390 rate
= params_rate(params
);
391 ret
= sst_hsw_stream_set_rate(hsw
, pcm_data
->stream
, rate
);
393 dev_err(rtd
->dev
, "error: could not set rate %d\n", rate
);
397 switch (params_format(params
)) {
398 case SNDRV_PCM_FORMAT_S16_LE
:
399 bits
= SST_HSW_DEPTH_16BIT
;
400 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 16);
402 case SNDRV_PCM_FORMAT_S24_LE
:
403 bits
= SST_HSW_DEPTH_32BIT
;
404 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 24);
406 case SNDRV_PCM_FORMAT_S8
:
407 bits
= SST_HSW_DEPTH_8BIT
;
408 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 8);
410 case SNDRV_PCM_FORMAT_S32_LE
:
411 bits
= SST_HSW_DEPTH_32BIT
;
412 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 32);
415 dev_err(rtd
->dev
, "error: invalid format %d\n",
416 params_format(params
));
420 ret
= sst_hsw_stream_set_bits(hsw
, pcm_data
->stream
, bits
);
422 dev_err(rtd
->dev
, "error: could not set bits %d\n", bits
);
426 /* we only support stereo atm */
427 channels
= params_channels(params
);
429 dev_err(rtd
->dev
, "error: invalid channels %d\n", channels
);
433 map
= create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO
);
434 sst_hsw_stream_set_map_config(hsw
, pcm_data
->stream
,
435 map
, SST_HSW_CHANNEL_CONFIG_STEREO
);
437 ret
= sst_hsw_stream_set_channels(hsw
, pcm_data
->stream
, channels
);
439 dev_err(rtd
->dev
, "error: could not set channels %d\n",
444 ret
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(params
));
446 dev_err(rtd
->dev
, "error: could not allocate %d bytes for PCM %d\n",
447 params_buffer_bytes(params
), ret
);
451 dmab
= snd_pcm_get_dma_buf(substream
);
453 ret
= create_adsp_page_table(substream
, pdata
, rtd
, runtime
->dma_area
,
454 runtime
->dma_bytes
, rtd
->cpu_dai
->id
);
458 sst_hsw_stream_set_style(hsw
, pcm_data
->stream
,
459 SST_HSW_INTERLEAVING_PER_CHANNEL
);
461 if (runtime
->dma_bytes
% PAGE_SIZE
)
462 pages
= (runtime
->dma_bytes
/ PAGE_SIZE
) + 1;
464 pages
= runtime
->dma_bytes
/ PAGE_SIZE
;
466 ret
= sst_hsw_stream_buffer(hsw
, pcm_data
->stream
,
467 pdata
->dmab
[rtd
->cpu_dai
->id
][substream
->stream
].addr
,
468 pages
, runtime
->dma_bytes
, 0,
469 snd_sgbuf_get_addr(dmab
, 0) >> PAGE_SHIFT
);
471 dev_err(rtd
->dev
, "error: failed to set DMA buffer %d\n", ret
);
475 dsp
= sst_hsw_get_dsp(hsw
);
477 module_data
= sst_module_get_from_id(dsp
, module_id
);
478 if (module_data
== NULL
) {
479 dev_err(rtd
->dev
, "error: failed to get module config\n");
483 /* we use hardcoded memory offsets atm, will be updated for new FW */
484 if (stream_type
== SST_HSW_STREAM_TYPE_CAPTURE
) {
485 sst_hsw_stream_set_module_info(hsw
, pcm_data
->stream
,
486 SST_HSW_MODULE_PCM_CAPTURE
, module_data
->entry
);
487 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
489 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
491 } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
492 sst_hsw_stream_set_module_info(hsw
, pcm_data
->stream
,
493 SST_HSW_MODULE_PCM_SYSTEM
, module_data
->entry
);
495 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
496 module_data
->offset
, module_data
->size
);
497 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
500 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
501 module_data
->offset
, module_data
->size
);
502 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
506 ret
= sst_hsw_stream_commit(hsw
, pcm_data
->stream
);
508 dev_err(rtd
->dev
, "error: failed to commit stream %d\n", ret
);
511 pcm_data
->allocated
= true;
513 ret
= sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 1);
515 dev_err(rtd
->dev
, "error: failed to pause %d\n", ret
);
520 static int hsw_pcm_hw_free(struct snd_pcm_substream
*substream
)
522 snd_pcm_lib_free_pages(substream
);
526 static int hsw_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
528 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
529 struct hsw_priv_data
*pdata
=
530 snd_soc_platform_get_drvdata(rtd
->platform
);
531 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
532 struct sst_hsw
*hsw
= pdata
->hsw
;
535 case SNDRV_PCM_TRIGGER_START
:
536 case SNDRV_PCM_TRIGGER_RESUME
:
537 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
538 sst_hsw_stream_resume(hsw
, pcm_data
->stream
, 0);
540 case SNDRV_PCM_TRIGGER_STOP
:
541 case SNDRV_PCM_TRIGGER_SUSPEND
:
542 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
543 sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 0);
552 static u32
hsw_notify_pointer(struct sst_hsw_stream
*stream
, void *data
)
554 struct hsw_pcm_data
*pcm_data
= data
;
555 struct snd_pcm_substream
*substream
= pcm_data
->substream
;
556 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
557 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
560 pos
= frames_to_bytes(runtime
,
561 (runtime
->control
->appl_ptr
% runtime
->buffer_size
));
563 dev_dbg(rtd
->dev
, "PCM: App pointer %d bytes\n", pos
);
565 /* let alsa know we have play a period */
566 snd_pcm_period_elapsed(substream
);
570 static snd_pcm_uframes_t
hsw_pcm_pointer(struct snd_pcm_substream
*substream
)
572 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
573 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
574 struct hsw_priv_data
*pdata
=
575 snd_soc_platform_get_drvdata(rtd
->platform
);
576 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
577 struct sst_hsw
*hsw
= pdata
->hsw
;
578 snd_pcm_uframes_t offset
;
580 u32 position
= sst_hsw_get_dsp_position(hsw
, pcm_data
->stream
);
582 offset
= bytes_to_frames(runtime
, position
);
583 ppos
= sst_hsw_get_dsp_presentation_position(hsw
, pcm_data
->stream
);
585 dev_dbg(rtd
->dev
, "PCM: DMA pointer %du bytes, pos %llu\n",
590 static int hsw_pcm_open(struct snd_pcm_substream
*substream
)
592 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
593 struct hsw_priv_data
*pdata
=
594 snd_soc_platform_get_drvdata(rtd
->platform
);
595 struct hsw_pcm_data
*pcm_data
;
596 struct sst_hsw
*hsw
= pdata
->hsw
;
598 pcm_data
= &pdata
->pcm
[rtd
->cpu_dai
->id
];
600 mutex_lock(&pcm_data
->mutex
);
602 snd_soc_pcm_set_drvdata(rtd
, pcm_data
);
603 pcm_data
->substream
= substream
;
605 snd_soc_set_runtime_hwparams(substream
, &hsw_pcm_hardware
);
607 pcm_data
->stream
= sst_hsw_stream_new(hsw
, rtd
->cpu_dai
->id
,
608 hsw_notify_pointer
, pcm_data
);
609 if (pcm_data
->stream
== NULL
) {
610 dev_err(rtd
->dev
, "error: failed to create stream\n");
611 mutex_unlock(&pcm_data
->mutex
);
615 /* Set previous saved volume */
616 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0,
617 0, pcm_data
->volume
[0]);
618 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0,
619 1, pcm_data
->volume
[1]);
621 mutex_unlock(&pcm_data
->mutex
);
625 static int hsw_pcm_close(struct snd_pcm_substream
*substream
)
627 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
628 struct hsw_priv_data
*pdata
=
629 snd_soc_platform_get_drvdata(rtd
->platform
);
630 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
631 struct sst_hsw
*hsw
= pdata
->hsw
;
634 mutex_lock(&pcm_data
->mutex
);
635 ret
= sst_hsw_stream_reset(hsw
, pcm_data
->stream
);
637 dev_dbg(rtd
->dev
, "error: reset stream failed %d\n", ret
);
641 ret
= sst_hsw_stream_free(hsw
, pcm_data
->stream
);
643 dev_dbg(rtd
->dev
, "error: free stream failed %d\n", ret
);
646 pcm_data
->allocated
= 0;
647 pcm_data
->stream
= NULL
;
650 mutex_unlock(&pcm_data
->mutex
);
654 static struct snd_pcm_ops hsw_pcm_ops
= {
655 .open
= hsw_pcm_open
,
656 .close
= hsw_pcm_close
,
657 .ioctl
= snd_pcm_lib_ioctl
,
658 .hw_params
= hsw_pcm_hw_params
,
659 .hw_free
= hsw_pcm_hw_free
,
660 .trigger
= hsw_pcm_trigger
,
661 .pointer
= hsw_pcm_pointer
,
662 .page
= snd_pcm_sgbuf_ops_page
,
665 static void hsw_pcm_free(struct snd_pcm
*pcm
)
667 snd_pcm_lib_preallocate_free_for_all(pcm
);
670 static int hsw_pcm_new(struct snd_soc_pcm_runtime
*rtd
)
672 struct snd_pcm
*pcm
= rtd
->pcm
;
673 struct snd_soc_platform
*platform
= rtd
->platform
;
674 struct sst_pdata
*pdata
= dev_get_platdata(platform
->dev
);
675 struct device
*dev
= pdata
->dma_dev
;
678 if (pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
||
679 pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
) {
680 ret
= snd_pcm_lib_preallocate_pages_for_all(pcm
,
681 SNDRV_DMA_TYPE_DEV_SG
,
683 hsw_pcm_hardware
.buffer_bytes_max
,
684 hsw_pcm_hardware
.buffer_bytes_max
);
686 dev_err(rtd
->dev
, "dma buffer allocation failed %d\n",
695 #define HSW_FORMATS \
696 (SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S24_LE | \
697 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
700 static struct snd_soc_dai_driver hsw_dais
[] = {
702 .name
= "System Pin",
704 .stream_name
= "System Playback",
707 .rates
= SNDRV_PCM_RATE_48000
,
708 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
713 .name
= "Offload0 Pin",
715 .stream_name
= "Offload0 Playback",
718 .rates
= SNDRV_PCM_RATE_8000_192000
,
719 .formats
= HSW_FORMATS
,
724 .name
= "Offload1 Pin",
726 .stream_name
= "Offload1 Playback",
729 .rates
= SNDRV_PCM_RATE_8000_192000
,
730 .formats
= HSW_FORMATS
,
734 .name
= "Loopback Pin",
736 .stream_name
= "Loopback Capture",
739 .rates
= SNDRV_PCM_RATE_48000
,
740 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
744 .name
= "Capture Pin",
746 .stream_name
= "Analog Capture",
749 .rates
= SNDRV_PCM_RATE_48000
,
750 .formats
= SNDRV_PCM_FMTBIT_S24_LE
| SNDRV_PCM_FMTBIT_S16_LE
,
755 static const struct snd_soc_dapm_widget widgets
[] = {
758 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
759 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
760 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
761 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
763 /* Global Playback Mixer */
764 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM
, 0, 0, NULL
, 0),
767 static const struct snd_soc_dapm_route graph
[] = {
770 {"Playback VMixer", NULL
, "System Playback"},
771 {"Playback VMixer", NULL
, "Offload0 Playback"},
772 {"Playback VMixer", NULL
, "Offload1 Playback"},
774 {"SSP0 CODEC OUT", NULL
, "Playback VMixer"},
776 {"Analog Capture", NULL
, "SSP0 CODEC IN"},
779 static int hsw_pcm_probe(struct snd_soc_platform
*platform
)
781 struct sst_pdata
*pdata
= dev_get_platdata(platform
->dev
);
782 struct hsw_priv_data
*priv_data
;
783 struct device
*dma_dev
;
789 dma_dev
= pdata
->dma_dev
;
791 priv_data
= devm_kzalloc(platform
->dev
, sizeof(*priv_data
), GFP_KERNEL
);
792 priv_data
->hsw
= pdata
->dsp
;
793 snd_soc_platform_set_drvdata(platform
, priv_data
);
795 /* allocate DSP buffer page tables */
796 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
798 mutex_init(&priv_data
->pcm
[i
].mutex
);
801 if (hsw_dais
[i
].playback
.channels_min
) {
802 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
803 PAGE_SIZE
, &priv_data
->dmab
[i
][0]);
809 if (hsw_dais
[i
].capture
.channels_min
) {
810 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
811 PAGE_SIZE
, &priv_data
->dmab
[i
][1]);
821 if (hsw_dais
[i
].playback
.channels_min
)
822 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
823 if (hsw_dais
[i
].capture
.channels_min
)
824 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
829 static int hsw_pcm_remove(struct snd_soc_platform
*platform
)
831 struct hsw_priv_data
*priv_data
=
832 snd_soc_platform_get_drvdata(platform
);
835 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
836 if (hsw_dais
[i
].playback
.channels_min
)
837 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
838 if (hsw_dais
[i
].capture
.channels_min
)
839 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
845 static struct snd_soc_platform_driver hsw_soc_platform
= {
846 .probe
= hsw_pcm_probe
,
847 .remove
= hsw_pcm_remove
,
849 .pcm_new
= hsw_pcm_new
,
850 .pcm_free
= hsw_pcm_free
,
851 .controls
= hsw_volume_controls
,
852 .num_controls
= ARRAY_SIZE(hsw_volume_controls
),
853 .dapm_widgets
= widgets
,
854 .num_dapm_widgets
= ARRAY_SIZE(widgets
),
855 .dapm_routes
= graph
,
856 .num_dapm_routes
= ARRAY_SIZE(graph
),
859 static const struct snd_soc_component_driver hsw_dai_component
= {
860 .name
= "haswell-dai",
863 static int hsw_pcm_dev_probe(struct platform_device
*pdev
)
865 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
868 ret
= sst_hsw_dsp_init(&pdev
->dev
, sst_pdata
);
872 ret
= snd_soc_register_platform(&pdev
->dev
, &hsw_soc_platform
);
876 ret
= snd_soc_register_component(&pdev
->dev
, &hsw_dai_component
,
877 hsw_dais
, ARRAY_SIZE(hsw_dais
));
884 snd_soc_unregister_platform(&pdev
->dev
);
886 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
890 static int hsw_pcm_dev_remove(struct platform_device
*pdev
)
892 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
894 snd_soc_unregister_platform(&pdev
->dev
);
895 snd_soc_unregister_component(&pdev
->dev
);
896 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
901 static struct platform_driver hsw_pcm_driver
= {
903 .name
= "haswell-pcm-audio",
904 .owner
= THIS_MODULE
,
907 .probe
= hsw_pcm_dev_probe
,
908 .remove
= hsw_pcm_dev_remove
,
910 module_platform_driver(hsw_pcm_driver
);
912 MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
913 MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
914 MODULE_LICENSE("GPL v2");
915 MODULE_ALIAS("platform:haswell-pcm-audio");