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/module.h>
21 #include <linux/delay.h>
23 #include <asm/pgtable.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/dmaengine_pcm.h>
28 #include <sound/soc.h>
29 #include <sound/tlv.h>
30 #include <sound/compress_driver.h>
32 #include "sst-haswell-ipc.h"
33 #include "sst-dsp-priv.h"
36 #define HSW_PCM_COUNT 6
37 #define HSW_VOLUME_MAX 0x7FFFFFFF /* 0dB */
39 /* simple volume table */
40 static const u32 volume_map
[] = {
74 #define HSW_PCM_PERIODS_MAX 64
75 #define HSW_PCM_PERIODS_MIN 2
77 static const struct snd_pcm_hardware hsw_pcm_hardware
= {
78 .info
= SNDRV_PCM_INFO_MMAP
|
79 SNDRV_PCM_INFO_MMAP_VALID
|
80 SNDRV_PCM_INFO_INTERLEAVED
|
81 SNDRV_PCM_INFO_PAUSE
|
82 SNDRV_PCM_INFO_RESUME
|
83 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP
,
84 .formats
= SNDRV_PCM_FMTBIT_S16_LE
| SNDRV_PCM_FORMAT_S24_LE
|
85 SNDRV_PCM_FMTBIT_S32_LE
,
86 .period_bytes_min
= PAGE_SIZE
,
87 .period_bytes_max
= (HSW_PCM_PERIODS_MAX
/ HSW_PCM_PERIODS_MIN
) * PAGE_SIZE
,
88 .periods_min
= HSW_PCM_PERIODS_MIN
,
89 .periods_max
= HSW_PCM_PERIODS_MAX
,
90 .buffer_bytes_max
= HSW_PCM_PERIODS_MAX
* PAGE_SIZE
,
93 /* private data for each PCM DSP stream */
96 struct sst_hsw_stream
*stream
;
98 struct snd_pcm_substream
*substream
;
99 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 inline u32
hsw_mixer_to_ipc(unsigned int value
)
118 if (value
>= ARRAY_SIZE(volume_map
))
119 return volume_map
[0];
121 return volume_map
[value
];
124 static inline unsigned int hsw_ipc_to_mixer(u32 value
)
128 for (i
= 0; i
< ARRAY_SIZE(volume_map
); i
++) {
129 if (volume_map
[i
] >= value
)
136 static int hsw_stream_volume_put(struct snd_kcontrol
*kcontrol
,
137 struct snd_ctl_elem_value
*ucontrol
)
139 struct snd_soc_platform
*platform
= snd_kcontrol_chip(kcontrol
);
140 struct soc_mixer_control
*mc
=
141 (struct soc_mixer_control
*)kcontrol
->private_value
;
142 struct hsw_priv_data
*pdata
=
143 snd_soc_platform_get_drvdata(platform
);
144 struct hsw_pcm_data
*pcm_data
= &pdata
->pcm
[mc
->reg
];
145 struct sst_hsw
*hsw
= pdata
->hsw
;
148 mutex_lock(&pcm_data
->mutex
);
150 if (!pcm_data
->stream
) {
151 pcm_data
->volume
[0] =
152 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
153 pcm_data
->volume
[1] =
154 hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
155 mutex_unlock(&pcm_data
->mutex
);
159 if (ucontrol
->value
.integer
.value
[0] ==
160 ucontrol
->value
.integer
.value
[1]) {
161 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
162 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 2, volume
);
164 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[0]);
165 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 0, volume
);
166 volume
= hsw_mixer_to_ipc(ucontrol
->value
.integer
.value
[1]);
167 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0, 1, volume
);
170 mutex_unlock(&pcm_data
->mutex
);
174 static int hsw_stream_volume_get(struct snd_kcontrol
*kcontrol
,
175 struct snd_ctl_elem_value
*ucontrol
)
177 struct snd_soc_platform
*platform
= snd_kcontrol_chip(kcontrol
);
178 struct soc_mixer_control
*mc
=
179 (struct soc_mixer_control
*)kcontrol
->private_value
;
180 struct hsw_priv_data
*pdata
=
181 snd_soc_platform_get_drvdata(platform
);
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_platform
*platform
= snd_kcontrol_chip(kcontrol
);
210 struct hsw_priv_data
*pdata
= snd_soc_platform_get_drvdata(platform
);
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_platform
*platform
= snd_kcontrol_chip(kcontrol
);
235 struct hsw_priv_data
*pdata
= snd_soc_platform_get_drvdata(platform
);
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 /* stream direction */
326 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
327 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
329 path_id
= SST_HSW_STREAM_PATH_SSP0_IN
;
331 /* DSP stream type depends on DAI ID */
332 switch (rtd
->cpu_dai
->id
) {
334 stream_type
= SST_HSW_STREAM_TYPE_SYSTEM
;
335 module_id
= SST_HSW_MODULE_PCM_SYSTEM
;
339 stream_type
= SST_HSW_STREAM_TYPE_RENDER
;
340 module_id
= SST_HSW_MODULE_PCM
;
343 /* path ID needs to be OUT for loopback */
344 stream_type
= SST_HSW_STREAM_TYPE_LOOPBACK
;
345 path_id
= SST_HSW_STREAM_PATH_SSP0_OUT
;
346 module_id
= SST_HSW_MODULE_PCM_REFERENCE
;
349 stream_type
= SST_HSW_STREAM_TYPE_CAPTURE
;
350 module_id
= SST_HSW_MODULE_PCM_CAPTURE
;
353 dev_err(rtd
->dev
, "error: invalid DAI ID %d\n",
358 ret
= sst_hsw_stream_format(hsw
, pcm_data
->stream
,
359 path_id
, stream_type
, SST_HSW_STREAM_FORMAT_PCM_FORMAT
);
361 dev_err(rtd
->dev
, "error: failed to set format %d\n", ret
);
365 rate
= params_rate(params
);
366 ret
= sst_hsw_stream_set_rate(hsw
, pcm_data
->stream
, rate
);
368 dev_err(rtd
->dev
, "error: could not set rate %d\n", rate
);
372 switch (params_format(params
)) {
373 case SNDRV_PCM_FORMAT_S16_LE
:
374 bits
= SST_HSW_DEPTH_16BIT
;
375 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 16);
377 case SNDRV_PCM_FORMAT_S24_LE
:
378 bits
= SST_HSW_DEPTH_24BIT
;
379 sst_hsw_stream_set_valid(hsw
, pcm_data
->stream
, 32);
382 dev_err(rtd
->dev
, "error: invalid format %d\n",
383 params_format(params
));
387 ret
= sst_hsw_stream_set_bits(hsw
, pcm_data
->stream
, bits
);
389 dev_err(rtd
->dev
, "error: could not set bits %d\n", bits
);
393 /* we only support stereo atm */
394 channels
= params_channels(params
);
396 dev_err(rtd
->dev
, "error: invalid channels %d\n", channels
);
400 map
= create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO
);
401 sst_hsw_stream_set_map_config(hsw
, pcm_data
->stream
,
402 map
, SST_HSW_CHANNEL_CONFIG_STEREO
);
404 ret
= sst_hsw_stream_set_channels(hsw
, pcm_data
->stream
, channels
);
406 dev_err(rtd
->dev
, "error: could not set channels %d\n",
411 ret
= snd_pcm_lib_malloc_pages(substream
, params_buffer_bytes(params
));
413 dev_err(rtd
->dev
, "error: could not allocate %d bytes for PCM %d\n",
414 params_buffer_bytes(params
), ret
);
418 dmab
= snd_pcm_get_dma_buf(substream
);
420 ret
= create_adsp_page_table(substream
, pdata
, rtd
, runtime
->dma_area
,
421 runtime
->dma_bytes
, rtd
->cpu_dai
->id
);
425 sst_hsw_stream_set_style(hsw
, pcm_data
->stream
,
426 SST_HSW_INTERLEAVING_PER_CHANNEL
);
428 if (runtime
->dma_bytes
% PAGE_SIZE
)
429 pages
= (runtime
->dma_bytes
/ PAGE_SIZE
) + 1;
431 pages
= runtime
->dma_bytes
/ PAGE_SIZE
;
433 ret
= sst_hsw_stream_buffer(hsw
, pcm_data
->stream
,
434 pdata
->dmab
[rtd
->cpu_dai
->id
][substream
->stream
].addr
,
435 pages
, runtime
->dma_bytes
, 0,
436 snd_sgbuf_get_addr(dmab
, 0) >> PAGE_SHIFT
);
438 dev_err(rtd
->dev
, "error: failed to set DMA buffer %d\n", ret
);
442 dsp
= sst_hsw_get_dsp(hsw
);
444 module_data
= sst_module_get_from_id(dsp
, module_id
);
445 if (module_data
== NULL
) {
446 dev_err(rtd
->dev
, "error: failed to get module config\n");
450 /* we use hardcoded memory offsets atm, will be updated for new FW */
451 if (stream_type
== SST_HSW_STREAM_TYPE_CAPTURE
) {
452 sst_hsw_stream_set_module_info(hsw
, pcm_data
->stream
,
453 SST_HSW_MODULE_PCM_CAPTURE
, module_data
->entry
);
454 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
456 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
458 } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
459 sst_hsw_stream_set_module_info(hsw
, pcm_data
->stream
,
460 SST_HSW_MODULE_PCM_SYSTEM
, module_data
->entry
);
462 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
463 module_data
->offset
, module_data
->size
);
464 sst_hsw_stream_set_pmemory_info(hsw
, pcm_data
->stream
,
467 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
468 module_data
->offset
, module_data
->size
);
469 sst_hsw_stream_set_smemory_info(hsw
, pcm_data
->stream
,
473 ret
= sst_hsw_stream_commit(hsw
, pcm_data
->stream
);
475 dev_err(rtd
->dev
, "error: failed to commit stream %d\n", ret
);
479 ret
= sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 1);
481 dev_err(rtd
->dev
, "error: failed to pause %d\n", ret
);
486 static int hsw_pcm_hw_free(struct snd_pcm_substream
*substream
)
488 snd_pcm_lib_free_pages(substream
);
492 static int hsw_pcm_trigger(struct snd_pcm_substream
*substream
, int cmd
)
494 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
495 struct hsw_priv_data
*pdata
=
496 snd_soc_platform_get_drvdata(rtd
->platform
);
497 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
498 struct sst_hsw
*hsw
= pdata
->hsw
;
501 case SNDRV_PCM_TRIGGER_START
:
502 case SNDRV_PCM_TRIGGER_RESUME
:
503 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
504 sst_hsw_stream_resume(hsw
, pcm_data
->stream
, 0);
506 case SNDRV_PCM_TRIGGER_STOP
:
507 case SNDRV_PCM_TRIGGER_SUSPEND
:
508 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
509 sst_hsw_stream_pause(hsw
, pcm_data
->stream
, 0);
518 static u32
hsw_notify_pointer(struct sst_hsw_stream
*stream
, void *data
)
520 struct hsw_pcm_data
*pcm_data
= data
;
521 struct snd_pcm_substream
*substream
= pcm_data
->substream
;
522 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
523 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
526 pos
= frames_to_bytes(runtime
,
527 (runtime
->control
->appl_ptr
% runtime
->buffer_size
));
529 dev_dbg(rtd
->dev
, "PCM: App pointer %d bytes\n", pos
);
531 /* let alsa know we have play a period */
532 snd_pcm_period_elapsed(substream
);
536 static snd_pcm_uframes_t
hsw_pcm_pointer(struct snd_pcm_substream
*substream
)
538 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
539 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
540 struct hsw_priv_data
*pdata
=
541 snd_soc_platform_get_drvdata(rtd
->platform
);
542 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
543 struct sst_hsw
*hsw
= pdata
->hsw
;
544 snd_pcm_uframes_t offset
;
546 offset
= bytes_to_frames(runtime
,
547 sst_hsw_get_dsp_position(hsw
, pcm_data
->stream
));
549 dev_dbg(rtd
->dev
, "PCM: DMA pointer %zu bytes\n",
550 frames_to_bytes(runtime
, (u32
)offset
));
554 static int hsw_pcm_open(struct snd_pcm_substream
*substream
)
556 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
557 struct hsw_priv_data
*pdata
=
558 snd_soc_platform_get_drvdata(rtd
->platform
);
559 struct hsw_pcm_data
*pcm_data
;
560 struct sst_hsw
*hsw
= pdata
->hsw
;
562 pcm_data
= &pdata
->pcm
[rtd
->cpu_dai
->id
];
564 mutex_lock(&pcm_data
->mutex
);
566 snd_soc_pcm_set_drvdata(rtd
, pcm_data
);
567 pcm_data
->substream
= substream
;
569 snd_soc_set_runtime_hwparams(substream
, &hsw_pcm_hardware
);
571 pcm_data
->stream
= sst_hsw_stream_new(hsw
, rtd
->cpu_dai
->id
,
572 hsw_notify_pointer
, pcm_data
);
573 if (pcm_data
->stream
== NULL
) {
574 dev_err(rtd
->dev
, "error: failed to create stream\n");
575 mutex_unlock(&pcm_data
->mutex
);
579 /* Set previous saved volume */
580 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0,
581 0, pcm_data
->volume
[0]);
582 sst_hsw_stream_set_volume(hsw
, pcm_data
->stream
, 0,
583 1, pcm_data
->volume
[1]);
585 mutex_unlock(&pcm_data
->mutex
);
589 static int hsw_pcm_close(struct snd_pcm_substream
*substream
)
591 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
592 struct hsw_priv_data
*pdata
=
593 snd_soc_platform_get_drvdata(rtd
->platform
);
594 struct hsw_pcm_data
*pcm_data
= snd_soc_pcm_get_drvdata(rtd
);
595 struct sst_hsw
*hsw
= pdata
->hsw
;
598 mutex_lock(&pcm_data
->mutex
);
599 ret
= sst_hsw_stream_reset(hsw
, pcm_data
->stream
);
601 dev_dbg(rtd
->dev
, "error: reset stream failed %d\n", ret
);
605 ret
= sst_hsw_stream_free(hsw
, pcm_data
->stream
);
607 dev_dbg(rtd
->dev
, "error: free stream failed %d\n", ret
);
610 pcm_data
->stream
= NULL
;
613 mutex_unlock(&pcm_data
->mutex
);
617 static struct snd_pcm_ops hsw_pcm_ops
= {
618 .open
= hsw_pcm_open
,
619 .close
= hsw_pcm_close
,
620 .ioctl
= snd_pcm_lib_ioctl
,
621 .hw_params
= hsw_pcm_hw_params
,
622 .hw_free
= hsw_pcm_hw_free
,
623 .trigger
= hsw_pcm_trigger
,
624 .pointer
= hsw_pcm_pointer
,
625 .page
= snd_pcm_sgbuf_ops_page
,
628 static void hsw_pcm_free(struct snd_pcm
*pcm
)
630 snd_pcm_lib_preallocate_free_for_all(pcm
);
633 static int hsw_pcm_new(struct snd_soc_pcm_runtime
*rtd
)
635 struct snd_pcm
*pcm
= rtd
->pcm
;
638 ret
= dma_coerce_mask_and_coherent(rtd
->card
->dev
, DMA_BIT_MASK(32));
642 if (pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
||
643 pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
) {
644 ret
= snd_pcm_lib_preallocate_pages_for_all(pcm
,
645 SNDRV_DMA_TYPE_DEV_SG
,
647 hsw_pcm_hardware
.buffer_bytes_max
,
648 hsw_pcm_hardware
.buffer_bytes_max
);
650 dev_err(rtd
->dev
, "dma buffer allocation failed %d\n",
659 #define HSW_FORMATS \
660 (SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S16_LE |\
661 SNDRV_PCM_FMTBIT_S32_LE)
663 static struct snd_soc_dai_driver hsw_dais
[] = {
665 .name
= "System Pin",
667 .stream_name
= "System Playback",
670 .rates
= SNDRV_PCM_RATE_48000
,
671 .formats
= SNDRV_PCM_FMTBIT_S16_LE
,
676 .name
= "Offload0 Pin",
678 .stream_name
= "Offload0 Playback",
681 .rates
= SNDRV_PCM_RATE_8000_192000
,
682 .formats
= HSW_FORMATS
,
687 .name
= "Offload1 Pin",
689 .stream_name
= "Offload1 Playback",
692 .rates
= SNDRV_PCM_RATE_8000_192000
,
693 .formats
= HSW_FORMATS
,
697 .name
= "Loopback Pin",
699 .stream_name
= "Loopback Capture",
702 .rates
= SNDRV_PCM_RATE_8000_192000
,
703 .formats
= HSW_FORMATS
,
707 .name
= "Capture Pin",
709 .stream_name
= "Analog Capture",
712 .rates
= SNDRV_PCM_RATE_8000_192000
,
713 .formats
= HSW_FORMATS
,
718 static const struct snd_soc_dapm_widget widgets
[] = {
721 SND_SOC_DAPM_AIF_IN("SSP0 CODEC IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
722 SND_SOC_DAPM_AIF_OUT("SSP0 CODEC OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
723 SND_SOC_DAPM_AIF_IN("SSP1 BT IN", NULL
, 0, SND_SOC_NOPM
, 0, 0),
724 SND_SOC_DAPM_AIF_OUT("SSP1 BT OUT", NULL
, 0, SND_SOC_NOPM
, 0, 0),
726 /* Global Playback Mixer */
727 SND_SOC_DAPM_MIXER("Playback VMixer", SND_SOC_NOPM
, 0, 0, NULL
, 0),
730 static const struct snd_soc_dapm_route graph
[] = {
733 {"Playback VMixer", NULL
, "System Playback"},
734 {"Playback VMixer", NULL
, "Offload0 Playback"},
735 {"Playback VMixer", NULL
, "Offload1 Playback"},
737 {"SSP0 CODEC OUT", NULL
, "Playback VMixer"},
739 {"Analog Capture", NULL
, "SSP0 CODEC IN"},
742 static int hsw_pcm_probe(struct snd_soc_platform
*platform
)
744 struct sst_pdata
*pdata
= dev_get_platdata(platform
->dev
);
745 struct hsw_priv_data
*priv_data
;
746 struct device
*dma_dev
= pdata
->dma_dev
;
752 priv_data
= devm_kzalloc(platform
->dev
, sizeof(*priv_data
), GFP_KERNEL
);
753 priv_data
->hsw
= pdata
->dsp
;
754 snd_soc_platform_set_drvdata(platform
, priv_data
);
756 /* allocate DSP buffer page tables */
757 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
759 mutex_init(&priv_data
->pcm
[i
].mutex
);
762 if (hsw_dais
[i
].playback
.channels_min
) {
763 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
764 PAGE_SIZE
, &priv_data
->dmab
[i
][0]);
770 if (hsw_dais
[i
].capture
.channels_min
) {
771 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dma_dev
,
772 PAGE_SIZE
, &priv_data
->dmab
[i
][1]);
782 if (hsw_dais
[i
].playback
.channels_min
)
783 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
784 if (hsw_dais
[i
].capture
.channels_min
)
785 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
790 static int hsw_pcm_remove(struct snd_soc_platform
*platform
)
792 struct hsw_priv_data
*priv_data
=
793 snd_soc_platform_get_drvdata(platform
);
796 for (i
= 0; i
< ARRAY_SIZE(hsw_dais
); i
++) {
797 if (hsw_dais
[i
].playback
.channels_min
)
798 snd_dma_free_pages(&priv_data
->dmab
[i
][0]);
799 if (hsw_dais
[i
].capture
.channels_min
)
800 snd_dma_free_pages(&priv_data
->dmab
[i
][1]);
806 static struct snd_soc_platform_driver hsw_soc_platform
= {
807 .probe
= hsw_pcm_probe
,
808 .remove
= hsw_pcm_remove
,
810 .pcm_new
= hsw_pcm_new
,
811 .pcm_free
= hsw_pcm_free
,
812 .controls
= hsw_volume_controls
,
813 .num_controls
= ARRAY_SIZE(hsw_volume_controls
),
814 .dapm_widgets
= widgets
,
815 .num_dapm_widgets
= ARRAY_SIZE(widgets
),
816 .dapm_routes
= graph
,
817 .num_dapm_routes
= ARRAY_SIZE(graph
),
820 static const struct snd_soc_component_driver hsw_dai_component
= {
821 .name
= "haswell-dai",
824 static int hsw_pcm_dev_probe(struct platform_device
*pdev
)
826 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
829 ret
= sst_hsw_dsp_init(&pdev
->dev
, sst_pdata
);
833 ret
= snd_soc_register_platform(&pdev
->dev
, &hsw_soc_platform
);
837 ret
= snd_soc_register_component(&pdev
->dev
, &hsw_dai_component
,
838 hsw_dais
, ARRAY_SIZE(hsw_dais
));
845 snd_soc_unregister_platform(&pdev
->dev
);
847 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
851 static int hsw_pcm_dev_remove(struct platform_device
*pdev
)
853 struct sst_pdata
*sst_pdata
= dev_get_platdata(&pdev
->dev
);
855 snd_soc_unregister_platform(&pdev
->dev
);
856 snd_soc_unregister_component(&pdev
->dev
);
857 sst_hsw_dsp_free(&pdev
->dev
, sst_pdata
);
862 static struct platform_driver hsw_pcm_driver
= {
864 .name
= "haswell-pcm-audio",
865 .owner
= THIS_MODULE
,
868 .probe
= hsw_pcm_dev_probe
,
869 .remove
= hsw_pcm_dev_remove
,
871 module_platform_driver(hsw_pcm_driver
);
873 MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
874 MODULE_DESCRIPTION("Haswell/Lynxpoint + Broadwell/Wildcatpoint PCM");
875 MODULE_LICENSE("GPL v2");
876 MODULE_ALIAS("platform:haswell-pcm-audio");