1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
3 // Copyright (c) 2018, Linaro Limited
5 #include <linux/init.h>
7 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/slab.h>
10 #include <sound/soc.h>
11 #include <sound/soc-dapm.h>
12 #include <sound/pcm.h>
13 #include <linux/spinlock.h>
14 #include <sound/compress_driver.h>
16 #include <linux/dma-mapping.h>
17 #include <linux/of_device.h>
18 #include <sound/pcm_params.h>
20 #include "q6routing.h"
21 #include "q6dsp-errno.h"
23 #define DRV_NAME "q6asm-fe-dai"
25 #define PLAYBACK_MIN_NUM_PERIODS 2
26 #define PLAYBACK_MAX_NUM_PERIODS 8
27 #define PLAYBACK_MAX_PERIOD_SIZE 65536
28 #define PLAYBACK_MIN_PERIOD_SIZE 128
29 #define CAPTURE_MIN_NUM_PERIODS 2
30 #define CAPTURE_MAX_NUM_PERIODS 8
31 #define CAPTURE_MAX_PERIOD_SIZE 4096
32 #define CAPTURE_MIN_PERIOD_SIZE 320
33 #define SID_MASK_DEFAULT 0xF
35 /* Default values used if user space does not set */
36 #define COMPR_PLAYBACK_MIN_FRAGMENT_SIZE (8 * 1024)
37 #define COMPR_PLAYBACK_MAX_FRAGMENT_SIZE (128 * 1024)
38 #define COMPR_PLAYBACK_MIN_NUM_FRAGMENTS (4)
39 #define COMPR_PLAYBACK_MAX_NUM_FRAGMENTS (16 * 4)
41 #define ALAC_CH_LAYOUT_MONO ((101 << 16) | 1)
42 #define ALAC_CH_LAYOUT_STEREO ((101 << 16) | 2)
45 Q6ASM_STREAM_IDLE
= 0,
50 struct q6asm_dai_rtd
{
51 struct snd_pcm_substream
*substream
;
52 struct snd_compr_stream
*cstream
;
53 struct snd_codec codec
;
54 struct snd_dma_buffer dma_buffer
;
57 unsigned int pcm_size
;
58 unsigned int pcm_count
;
59 unsigned int pcm_irq_pos
; /* IRQ position */
61 unsigned int bytes_sent
;
62 unsigned int bytes_received
;
63 unsigned int copied_total
;
64 uint16_t bits_per_sample
;
65 uint16_t source
; /* Encoding source bit mask */
66 struct audio_client
*audio_client
;
67 uint32_t next_track_stream_id
;
71 enum stream_state state
;
72 uint32_t initial_samples_drop
;
73 uint32_t trailing_samples_drop
;
77 struct q6asm_dai_data
{
78 struct snd_soc_dai_driver
*dais
;
83 static const struct snd_pcm_hardware q6asm_dai_hardware_capture
= {
84 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_BATCH
|
85 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
86 SNDRV_PCM_INFO_MMAP_VALID
|
87 SNDRV_PCM_INFO_INTERLEAVED
|
88 SNDRV_PCM_INFO_PAUSE
| SNDRV_PCM_INFO_RESUME
),
89 .formats
= (SNDRV_PCM_FMTBIT_S16_LE
|
90 SNDRV_PCM_FMTBIT_S24_LE
),
91 .rates
= SNDRV_PCM_RATE_8000_48000
,
96 .buffer_bytes_max
= CAPTURE_MAX_NUM_PERIODS
*
97 CAPTURE_MAX_PERIOD_SIZE
,
98 .period_bytes_min
= CAPTURE_MIN_PERIOD_SIZE
,
99 .period_bytes_max
= CAPTURE_MAX_PERIOD_SIZE
,
100 .periods_min
= CAPTURE_MIN_NUM_PERIODS
,
101 .periods_max
= CAPTURE_MAX_NUM_PERIODS
,
105 static struct snd_pcm_hardware q6asm_dai_hardware_playback
= {
106 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_BATCH
|
107 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
108 SNDRV_PCM_INFO_MMAP_VALID
|
109 SNDRV_PCM_INFO_INTERLEAVED
|
110 SNDRV_PCM_INFO_PAUSE
| SNDRV_PCM_INFO_RESUME
),
111 .formats
= (SNDRV_PCM_FMTBIT_S16_LE
|
112 SNDRV_PCM_FMTBIT_S24_LE
),
113 .rates
= SNDRV_PCM_RATE_8000_192000
,
118 .buffer_bytes_max
= (PLAYBACK_MAX_NUM_PERIODS
*
119 PLAYBACK_MAX_PERIOD_SIZE
),
120 .period_bytes_min
= PLAYBACK_MIN_PERIOD_SIZE
,
121 .period_bytes_max
= PLAYBACK_MAX_PERIOD_SIZE
,
122 .periods_min
= PLAYBACK_MIN_NUM_PERIODS
,
123 .periods_max
= PLAYBACK_MAX_NUM_PERIODS
,
127 #define Q6ASM_FEDAI_DRIVER(num) { \
129 .stream_name = "MultiMedia"#num" Playback", \
130 .rates = (SNDRV_PCM_RATE_8000_192000| \
131 SNDRV_PCM_RATE_KNOT), \
132 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \
133 SNDRV_PCM_FMTBIT_S24_LE), \
137 .rate_max = 192000, \
140 .stream_name = "MultiMedia"#num" Capture", \
141 .rates = (SNDRV_PCM_RATE_8000_48000| \
142 SNDRV_PCM_RATE_KNOT), \
143 .formats = (SNDRV_PCM_FMTBIT_S16_LE | \
144 SNDRV_PCM_FMTBIT_S24_LE), \
150 .name = "MultiMedia"#num, \
151 .id = MSM_FRONTEND_DAI_MULTIMEDIA##num, \
154 /* Conventional and unconventional sample rate supported */
155 static unsigned int supported_sample_rates
[] = {
156 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
157 88200, 96000, 176400, 192000
160 static struct snd_pcm_hw_constraint_list constraints_sample_rates
= {
161 .count
= ARRAY_SIZE(supported_sample_rates
),
162 .list
= supported_sample_rates
,
166 static const struct snd_compr_codec_caps q6asm_compr_caps
= {
167 .num_descriptors
= 1,
168 .descriptor
[0].max_ch
= 2,
169 .descriptor
[0].sample_rates
= { 8000, 11025, 12000, 16000, 22050,
170 24000, 32000, 44100, 48000, 88200,
171 96000, 176400, 192000 },
172 .descriptor
[0].num_sample_rates
= 13,
173 .descriptor
[0].bit_rate
[0] = 320,
174 .descriptor
[0].bit_rate
[1] = 128,
175 .descriptor
[0].num_bitrates
= 2,
176 .descriptor
[0].profiles
= 0,
177 .descriptor
[0].modes
= SND_AUDIOCHANMODE_MP3_STEREO
,
178 .descriptor
[0].formats
= 0,
181 static void event_handler(uint32_t opcode
, uint32_t token
,
182 void *payload
, void *priv
)
184 struct q6asm_dai_rtd
*prtd
= priv
;
185 struct snd_pcm_substream
*substream
= prtd
->substream
;
188 case ASM_CLIENT_EVENT_CMD_RUN_DONE
:
189 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
190 q6asm_write_async(prtd
->audio_client
, prtd
->stream_id
,
191 prtd
->pcm_count
, 0, 0, 0);
193 case ASM_CLIENT_EVENT_CMD_EOS_DONE
:
194 prtd
->state
= Q6ASM_STREAM_STOPPED
;
196 case ASM_CLIENT_EVENT_DATA_WRITE_DONE
: {
197 prtd
->pcm_irq_pos
+= prtd
->pcm_count
;
198 snd_pcm_period_elapsed(substream
);
199 if (prtd
->state
== Q6ASM_STREAM_RUNNING
)
200 q6asm_write_async(prtd
->audio_client
, prtd
->stream_id
,
201 prtd
->pcm_count
, 0, 0, 0);
205 case ASM_CLIENT_EVENT_DATA_READ_DONE
:
206 prtd
->pcm_irq_pos
+= prtd
->pcm_count
;
207 snd_pcm_period_elapsed(substream
);
208 if (prtd
->state
== Q6ASM_STREAM_RUNNING
)
209 q6asm_read(prtd
->audio_client
, prtd
->stream_id
);
217 static int q6asm_dai_prepare(struct snd_soc_component
*component
,
218 struct snd_pcm_substream
*substream
)
220 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
221 struct snd_soc_pcm_runtime
*soc_prtd
= asoc_substream_to_rtd(substream
);
222 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
223 struct q6asm_dai_data
*pdata
;
224 struct device
*dev
= component
->dev
;
227 pdata
= snd_soc_component_get_drvdata(component
);
231 if (!prtd
|| !prtd
->audio_client
) {
232 dev_err(dev
, "%s: private data null or audio client freed\n",
237 prtd
->pcm_count
= snd_pcm_lib_period_bytes(substream
);
238 prtd
->pcm_irq_pos
= 0;
239 /* rate and channels are sent to audio driver */
241 /* clear the previous setup if any */
242 q6asm_cmd(prtd
->audio_client
, prtd
->stream_id
, CMD_CLOSE
);
243 q6asm_unmap_memory_regions(substream
->stream
,
245 q6routing_stream_close(soc_prtd
->dai_link
->id
,
249 ret
= q6asm_map_memory_regions(substream
->stream
, prtd
->audio_client
,
251 (prtd
->pcm_size
/ prtd
->periods
),
255 dev_err(dev
, "Audio Start: Buffer Allocation failed rc = %d\n",
260 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
261 ret
= q6asm_open_write(prtd
->audio_client
, prtd
->stream_id
,
263 0, prtd
->bits_per_sample
, false);
264 } else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
265 ret
= q6asm_open_read(prtd
->audio_client
, prtd
->stream_id
,
267 prtd
->bits_per_sample
);
271 dev_err(dev
, "%s: q6asm_open_write failed\n", __func__
);
272 q6asm_audio_client_free(prtd
->audio_client
);
273 prtd
->audio_client
= NULL
;
277 prtd
->session_id
= q6asm_get_session_id(prtd
->audio_client
);
278 ret
= q6routing_stream_open(soc_prtd
->dai_link
->id
, LEGACY_PCM_MODE
,
279 prtd
->session_id
, substream
->stream
);
281 dev_err(dev
, "%s: stream reg failed ret:%d\n", __func__
, ret
);
285 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
286 ret
= q6asm_media_format_block_multi_ch_pcm(
287 prtd
->audio_client
, prtd
->stream_id
,
288 runtime
->rate
, runtime
->channels
, NULL
,
289 prtd
->bits_per_sample
);
290 } else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
) {
291 ret
= q6asm_enc_cfg_blk_pcm_format_support(prtd
->audio_client
,
295 prtd
->bits_per_sample
);
297 /* Queue the buffers */
298 for (i
= 0; i
< runtime
->periods
; i
++)
299 q6asm_read(prtd
->audio_client
, prtd
->stream_id
);
303 dev_info(dev
, "%s: CMD Format block failed\n", __func__
);
305 prtd
->state
= Q6ASM_STREAM_RUNNING
;
310 static int q6asm_dai_trigger(struct snd_soc_component
*component
,
311 struct snd_pcm_substream
*substream
, int cmd
)
314 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
315 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
318 case SNDRV_PCM_TRIGGER_START
:
319 case SNDRV_PCM_TRIGGER_RESUME
:
320 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
321 ret
= q6asm_run_nowait(prtd
->audio_client
, prtd
->stream_id
,
324 case SNDRV_PCM_TRIGGER_STOP
:
325 prtd
->state
= Q6ASM_STREAM_STOPPED
;
326 ret
= q6asm_cmd_nowait(prtd
->audio_client
, prtd
->stream_id
,
329 case SNDRV_PCM_TRIGGER_SUSPEND
:
330 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
331 ret
= q6asm_cmd_nowait(prtd
->audio_client
, prtd
->stream_id
,
342 static int q6asm_dai_open(struct snd_soc_component
*component
,
343 struct snd_pcm_substream
*substream
)
345 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
346 struct snd_soc_pcm_runtime
*soc_prtd
= asoc_substream_to_rtd(substream
);
347 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(soc_prtd
, 0);
348 struct q6asm_dai_rtd
*prtd
;
349 struct q6asm_dai_data
*pdata
;
350 struct device
*dev
= component
->dev
;
354 stream_id
= cpu_dai
->driver
->id
;
356 pdata
= snd_soc_component_get_drvdata(component
);
358 dev_err(dev
, "Drv data not found ..\n");
362 prtd
= kzalloc(sizeof(struct q6asm_dai_rtd
), GFP_KERNEL
);
366 prtd
->substream
= substream
;
367 prtd
->audio_client
= q6asm_audio_client_alloc(dev
,
368 (q6asm_cb
)event_handler
, prtd
, stream_id
,
370 if (IS_ERR(prtd
->audio_client
)) {
371 dev_info(dev
, "%s: Could not allocate memory\n", __func__
);
372 ret
= PTR_ERR(prtd
->audio_client
);
377 /* DSP expects stream id from 1 */
380 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
381 runtime
->hw
= q6asm_dai_hardware_playback
;
382 else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
383 runtime
->hw
= q6asm_dai_hardware_capture
;
385 ret
= snd_pcm_hw_constraint_list(runtime
, 0,
386 SNDRV_PCM_HW_PARAM_RATE
,
387 &constraints_sample_rates
);
389 dev_info(dev
, "snd_pcm_hw_constraint_list failed\n");
390 /* Ensure that buffer size is a multiple of period size */
391 ret
= snd_pcm_hw_constraint_integer(runtime
,
392 SNDRV_PCM_HW_PARAM_PERIODS
);
394 dev_info(dev
, "snd_pcm_hw_constraint_integer failed\n");
396 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
397 ret
= snd_pcm_hw_constraint_minmax(runtime
,
398 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
,
399 PLAYBACK_MIN_NUM_PERIODS
* PLAYBACK_MIN_PERIOD_SIZE
,
400 PLAYBACK_MAX_NUM_PERIODS
* PLAYBACK_MAX_PERIOD_SIZE
);
402 dev_err(dev
, "constraint for buffer bytes min max ret = %d\n",
407 ret
= snd_pcm_hw_constraint_step(runtime
, 0,
408 SNDRV_PCM_HW_PARAM_PERIOD_BYTES
, 32);
410 dev_err(dev
, "constraint for period bytes step ret = %d\n",
413 ret
= snd_pcm_hw_constraint_step(runtime
, 0,
414 SNDRV_PCM_HW_PARAM_BUFFER_BYTES
, 32);
416 dev_err(dev
, "constraint for buffer bytes step ret = %d\n",
420 runtime
->private_data
= prtd
;
422 snd_soc_set_runtime_hwparams(substream
, &q6asm_dai_hardware_playback
);
424 runtime
->dma_bytes
= q6asm_dai_hardware_playback
.buffer_bytes_max
;
428 prtd
->phys
= substream
->dma_buffer
.addr
;
430 prtd
->phys
= substream
->dma_buffer
.addr
| (pdata
->sid
<< 32);
432 snd_pcm_set_runtime_buffer(substream
, &substream
->dma_buffer
);
437 static int q6asm_dai_close(struct snd_soc_component
*component
,
438 struct snd_pcm_substream
*substream
)
440 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
441 struct snd_soc_pcm_runtime
*soc_prtd
= asoc_substream_to_rtd(substream
);
442 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
444 if (prtd
->audio_client
) {
446 q6asm_cmd(prtd
->audio_client
, prtd
->stream_id
,
449 q6asm_unmap_memory_regions(substream
->stream
,
451 q6asm_audio_client_free(prtd
->audio_client
);
452 prtd
->audio_client
= NULL
;
454 q6routing_stream_close(soc_prtd
->dai_link
->id
,
460 static snd_pcm_uframes_t
q6asm_dai_pointer(struct snd_soc_component
*component
,
461 struct snd_pcm_substream
*substream
)
464 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
465 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
467 if (prtd
->pcm_irq_pos
>= prtd
->pcm_size
)
468 prtd
->pcm_irq_pos
= 0;
470 return bytes_to_frames(runtime
, (prtd
->pcm_irq_pos
));
473 static int q6asm_dai_mmap(struct snd_soc_component
*component
,
474 struct snd_pcm_substream
*substream
,
475 struct vm_area_struct
*vma
)
477 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
478 struct device
*dev
= component
->dev
;
480 return dma_mmap_coherent(dev
, vma
,
481 runtime
->dma_area
, runtime
->dma_addr
,
485 static int q6asm_dai_hw_params(struct snd_soc_component
*component
,
486 struct snd_pcm_substream
*substream
,
487 struct snd_pcm_hw_params
*params
)
489 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
490 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
492 prtd
->pcm_size
= params_buffer_bytes(params
);
493 prtd
->periods
= params_periods(params
);
495 switch (params_format(params
)) {
496 case SNDRV_PCM_FORMAT_S16_LE
:
497 prtd
->bits_per_sample
= 16;
499 case SNDRV_PCM_FORMAT_S24_LE
:
500 prtd
->bits_per_sample
= 24;
507 static void compress_event_handler(uint32_t opcode
, uint32_t token
,
508 void *payload
, void *priv
)
510 struct q6asm_dai_rtd
*prtd
= priv
;
511 struct snd_compr_stream
*substream
= prtd
->cstream
;
515 uint32_t bytes_written
, bytes_to_write
;
516 bool is_last_buffer
= false;
519 case ASM_CLIENT_EVENT_CMD_RUN_DONE
:
520 spin_lock_irqsave(&prtd
->lock
, flags
);
521 if (!prtd
->bytes_sent
) {
522 q6asm_stream_remove_initial_silence(prtd
->audio_client
,
524 prtd
->initial_samples_drop
);
526 q6asm_write_async(prtd
->audio_client
, prtd
->stream_id
,
527 prtd
->pcm_count
, 0, 0, 0);
528 prtd
->bytes_sent
+= prtd
->pcm_count
;
531 spin_unlock_irqrestore(&prtd
->lock
, flags
);
534 case ASM_CLIENT_EVENT_CMD_EOS_DONE
:
535 spin_lock_irqsave(&prtd
->lock
, flags
);
536 if (prtd
->notify_on_drain
) {
537 if (substream
->partial_drain
) {
539 * Close old stream and make it stale, switch
540 * the active stream now!
542 q6asm_cmd_nowait(prtd
->audio_client
,
546 * vaild stream ids start from 1, So we are
547 * toggling this between 1 and 2.
549 prtd
->stream_id
= (prtd
->stream_id
== 1 ? 2 : 1);
552 snd_compr_drain_notify(prtd
->cstream
);
553 prtd
->notify_on_drain
= false;
556 prtd
->state
= Q6ASM_STREAM_STOPPED
;
558 spin_unlock_irqrestore(&prtd
->lock
, flags
);
561 case ASM_CLIENT_EVENT_DATA_WRITE_DONE
:
562 spin_lock_irqsave(&prtd
->lock
, flags
);
564 bytes_written
= token
>> ASM_WRITE_TOKEN_LEN_SHIFT
;
565 prtd
->copied_total
+= bytes_written
;
566 snd_compr_fragment_elapsed(substream
);
568 if (prtd
->state
!= Q6ASM_STREAM_RUNNING
) {
569 spin_unlock_irqrestore(&prtd
->lock
, flags
);
573 avail
= prtd
->bytes_received
- prtd
->bytes_sent
;
574 if (avail
> prtd
->pcm_count
) {
575 bytes_to_write
= prtd
->pcm_count
;
577 if (substream
->partial_drain
|| prtd
->notify_on_drain
)
578 is_last_buffer
= true;
579 bytes_to_write
= avail
;
582 if (bytes_to_write
) {
583 if (substream
->partial_drain
&& is_last_buffer
) {
584 wflags
|= ASM_LAST_BUFFER_FLAG
;
585 q6asm_stream_remove_trailing_silence(prtd
->audio_client
,
587 prtd
->trailing_samples_drop
);
590 q6asm_write_async(prtd
->audio_client
, prtd
->stream_id
,
591 bytes_to_write
, 0, 0, wflags
);
593 prtd
->bytes_sent
+= bytes_to_write
;
596 if (prtd
->notify_on_drain
&& is_last_buffer
)
597 q6asm_cmd_nowait(prtd
->audio_client
,
598 prtd
->stream_id
, CMD_EOS
);
600 spin_unlock_irqrestore(&prtd
->lock
, flags
);
608 static int q6asm_dai_compr_open(struct snd_soc_component
*component
,
609 struct snd_compr_stream
*stream
)
611 struct snd_soc_pcm_runtime
*rtd
= stream
->private_data
;
612 struct snd_compr_runtime
*runtime
= stream
->runtime
;
613 struct snd_soc_dai
*cpu_dai
= asoc_rtd_to_cpu(rtd
, 0);
614 struct q6asm_dai_data
*pdata
;
615 struct device
*dev
= component
->dev
;
616 struct q6asm_dai_rtd
*prtd
;
617 int stream_id
, size
, ret
;
619 stream_id
= cpu_dai
->driver
->id
;
620 pdata
= snd_soc_component_get_drvdata(component
);
622 dev_err(dev
, "Drv data not found ..\n");
626 prtd
= kzalloc(sizeof(*prtd
), GFP_KERNEL
);
630 /* DSP expects stream id from 1 */
633 prtd
->cstream
= stream
;
634 prtd
->audio_client
= q6asm_audio_client_alloc(dev
,
635 (q6asm_cb
)compress_event_handler
,
636 prtd
, stream_id
, LEGACY_PCM_MODE
);
637 if (IS_ERR(prtd
->audio_client
)) {
638 dev_err(dev
, "Could not allocate memory\n");
639 ret
= PTR_ERR(prtd
->audio_client
);
643 size
= COMPR_PLAYBACK_MAX_FRAGMENT_SIZE
*
644 COMPR_PLAYBACK_MAX_NUM_FRAGMENTS
;
645 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dev
, size
,
648 dev_err(dev
, "Cannot allocate buffer(s)\n");
653 prtd
->phys
= prtd
->dma_buffer
.addr
;
655 prtd
->phys
= prtd
->dma_buffer
.addr
| (pdata
->sid
<< 32);
657 snd_compr_set_runtime_buffer(stream
, &prtd
->dma_buffer
);
658 spin_lock_init(&prtd
->lock
);
659 runtime
->private_data
= prtd
;
664 q6asm_audio_client_free(prtd
->audio_client
);
671 static int q6asm_dai_compr_free(struct snd_soc_component
*component
,
672 struct snd_compr_stream
*stream
)
674 struct snd_compr_runtime
*runtime
= stream
->runtime
;
675 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
676 struct snd_soc_pcm_runtime
*rtd
= stream
->private_data
;
678 if (prtd
->audio_client
) {
680 q6asm_cmd(prtd
->audio_client
, prtd
->stream_id
,
682 if (prtd
->next_track_stream_id
) {
683 q6asm_cmd(prtd
->audio_client
,
684 prtd
->next_track_stream_id
,
689 snd_dma_free_pages(&prtd
->dma_buffer
);
690 q6asm_unmap_memory_regions(stream
->direction
,
692 q6asm_audio_client_free(prtd
->audio_client
);
693 prtd
->audio_client
= NULL
;
695 q6routing_stream_close(rtd
->dai_link
->id
, stream
->direction
);
701 static int __q6asm_dai_compr_set_codec_params(struct snd_soc_component
*component
,
702 struct snd_compr_stream
*stream
,
703 struct snd_codec
*codec
,
706 struct snd_compr_runtime
*runtime
= stream
->runtime
;
707 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
708 struct q6asm_flac_cfg flac_cfg
;
709 struct q6asm_wma_cfg wma_cfg
;
710 struct q6asm_alac_cfg alac_cfg
;
711 struct q6asm_ape_cfg ape_cfg
;
712 unsigned int wma_v9
= 0;
713 struct device
*dev
= component
->dev
;
715 union snd_codec_options
*codec_options
;
716 struct snd_dec_flac
*flac
;
717 struct snd_dec_wma
*wma
;
718 struct snd_dec_alac
*alac
;
719 struct snd_dec_ape
*ape
;
721 codec_options
= &(prtd
->codec
.options
);
723 memcpy(&prtd
->codec
, codec
, sizeof(*codec
));
726 case SND_AUDIOCODEC_FLAC
:
728 memset(&flac_cfg
, 0x0, sizeof(struct q6asm_flac_cfg
));
729 flac
= &codec_options
->flac_d
;
731 flac_cfg
.ch_cfg
= codec
->ch_in
;
732 flac_cfg
.sample_rate
= codec
->sample_rate
;
733 flac_cfg
.stream_info_present
= 1;
734 flac_cfg
.sample_size
= flac
->sample_size
;
735 flac_cfg
.min_blk_size
= flac
->min_blk_size
;
736 flac_cfg
.max_blk_size
= flac
->max_blk_size
;
737 flac_cfg
.max_frame_size
= flac
->max_frame_size
;
738 flac_cfg
.min_frame_size
= flac
->min_frame_size
;
740 ret
= q6asm_stream_media_format_block_flac(prtd
->audio_client
,
744 dev_err(dev
, "FLAC CMD Format block failed:%d\n", ret
);
749 case SND_AUDIOCODEC_WMA
:
750 wma
= &codec_options
->wma_d
;
752 memset(&wma_cfg
, 0x0, sizeof(struct q6asm_wma_cfg
));
754 wma_cfg
.sample_rate
= codec
->sample_rate
;
755 wma_cfg
.num_channels
= codec
->ch_in
;
756 wma_cfg
.bytes_per_sec
= codec
->bit_rate
/ 8;
757 wma_cfg
.block_align
= codec
->align
;
758 wma_cfg
.bits_per_sample
= prtd
->bits_per_sample
;
759 wma_cfg
.enc_options
= wma
->encoder_option
;
760 wma_cfg
.adv_enc_options
= wma
->adv_encoder_option
;
761 wma_cfg
.adv_enc_options2
= wma
->adv_encoder_option2
;
763 if (wma_cfg
.num_channels
== 1)
764 wma_cfg
.channel_mask
= 4; /* Mono Center */
765 else if (wma_cfg
.num_channels
== 2)
766 wma_cfg
.channel_mask
= 3; /* Stereo FL/FR */
770 /* check the codec profile */
771 switch (codec
->profile
) {
772 case SND_AUDIOPROFILE_WMA9
:
773 wma_cfg
.fmtag
= 0x161;
777 case SND_AUDIOPROFILE_WMA10
:
778 wma_cfg
.fmtag
= 0x166;
781 case SND_AUDIOPROFILE_WMA9_PRO
:
782 wma_cfg
.fmtag
= 0x162;
785 case SND_AUDIOPROFILE_WMA9_LOSSLESS
:
786 wma_cfg
.fmtag
= 0x163;
789 case SND_AUDIOPROFILE_WMA10_LOSSLESS
:
790 wma_cfg
.fmtag
= 0x167;
794 dev_err(dev
, "Unknown WMA profile:%x\n",
800 ret
= q6asm_stream_media_format_block_wma_v9(
801 prtd
->audio_client
, stream_id
,
804 ret
= q6asm_stream_media_format_block_wma_v10(
805 prtd
->audio_client
, stream_id
,
808 dev_err(dev
, "WMA9 CMD failed:%d\n", ret
);
813 case SND_AUDIOCODEC_ALAC
:
814 memset(&alac_cfg
, 0x0, sizeof(alac_cfg
));
815 alac
= &codec_options
->alac_d
;
817 alac_cfg
.sample_rate
= codec
->sample_rate
;
818 alac_cfg
.avg_bit_rate
= codec
->bit_rate
;
819 alac_cfg
.bit_depth
= prtd
->bits_per_sample
;
820 alac_cfg
.num_channels
= codec
->ch_in
;
822 alac_cfg
.frame_length
= alac
->frame_length
;
823 alac_cfg
.pb
= alac
->pb
;
824 alac_cfg
.mb
= alac
->mb
;
825 alac_cfg
.kb
= alac
->kb
;
826 alac_cfg
.max_run
= alac
->max_run
;
827 alac_cfg
.compatible_version
= alac
->compatible_version
;
828 alac_cfg
.max_frame_bytes
= alac
->max_frame_bytes
;
830 switch (codec
->ch_in
) {
832 alac_cfg
.channel_layout_tag
= ALAC_CH_LAYOUT_MONO
;
835 alac_cfg
.channel_layout_tag
= ALAC_CH_LAYOUT_STEREO
;
838 ret
= q6asm_stream_media_format_block_alac(prtd
->audio_client
,
842 dev_err(dev
, "ALAC CMD Format block failed:%d\n", ret
);
847 case SND_AUDIOCODEC_APE
:
848 memset(&ape_cfg
, 0x0, sizeof(ape_cfg
));
849 ape
= &codec_options
->ape_d
;
851 ape_cfg
.sample_rate
= codec
->sample_rate
;
852 ape_cfg
.num_channels
= codec
->ch_in
;
853 ape_cfg
.bits_per_sample
= prtd
->bits_per_sample
;
855 ape_cfg
.compatible_version
= ape
->compatible_version
;
856 ape_cfg
.compression_level
= ape
->compression_level
;
857 ape_cfg
.format_flags
= ape
->format_flags
;
858 ape_cfg
.blocks_per_frame
= ape
->blocks_per_frame
;
859 ape_cfg
.final_frame_blocks
= ape
->final_frame_blocks
;
860 ape_cfg
.total_frames
= ape
->total_frames
;
861 ape_cfg
.seek_table_present
= ape
->seek_table_present
;
863 ret
= q6asm_stream_media_format_block_ape(prtd
->audio_client
,
867 dev_err(dev
, "APE CMD Format block failed:%d\n", ret
);
879 static int q6asm_dai_compr_set_params(struct snd_soc_component
*component
,
880 struct snd_compr_stream
*stream
,
881 struct snd_compr_params
*params
)
883 struct snd_compr_runtime
*runtime
= stream
->runtime
;
884 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
885 struct snd_soc_pcm_runtime
*rtd
= stream
->private_data
;
886 int dir
= stream
->direction
;
887 struct q6asm_dai_data
*pdata
;
888 struct device
*dev
= component
->dev
;
891 pdata
= snd_soc_component_get_drvdata(component
);
895 if (!prtd
|| !prtd
->audio_client
) {
896 dev_err(dev
, "private data null or audio client freed\n");
900 prtd
->periods
= runtime
->fragments
;
901 prtd
->pcm_count
= runtime
->fragment_size
;
902 prtd
->pcm_size
= runtime
->fragments
* runtime
->fragment_size
;
903 prtd
->bits_per_sample
= 16;
905 if (dir
== SND_COMPRESS_PLAYBACK
) {
906 ret
= q6asm_open_write(prtd
->audio_client
, prtd
->stream_id
, params
->codec
.id
,
907 params
->codec
.profile
, prtd
->bits_per_sample
,
911 dev_err(dev
, "q6asm_open_write failed\n");
912 q6asm_audio_client_free(prtd
->audio_client
);
913 prtd
->audio_client
= NULL
;
918 prtd
->session_id
= q6asm_get_session_id(prtd
->audio_client
);
919 ret
= q6routing_stream_open(rtd
->dai_link
->id
, LEGACY_PCM_MODE
,
920 prtd
->session_id
, dir
);
922 dev_err(dev
, "Stream reg failed ret:%d\n", ret
);
926 ret
= __q6asm_dai_compr_set_codec_params(component
, stream
,
930 dev_err(dev
, "codec param setup failed ret:%d\n", ret
);
934 ret
= q6asm_map_memory_regions(dir
, prtd
->audio_client
, prtd
->phys
,
935 (prtd
->pcm_size
/ prtd
->periods
),
939 dev_err(dev
, "Buffer Mapping failed ret:%d\n", ret
);
943 prtd
->state
= Q6ASM_STREAM_RUNNING
;
948 static int q6asm_dai_compr_set_metadata(struct snd_soc_component
*component
,
949 struct snd_compr_stream
*stream
,
950 struct snd_compr_metadata
*metadata
)
952 struct snd_compr_runtime
*runtime
= stream
->runtime
;
953 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
956 switch (metadata
->key
) {
957 case SNDRV_COMPRESS_ENCODER_PADDING
:
958 prtd
->trailing_samples_drop
= metadata
->value
[0];
960 case SNDRV_COMPRESS_ENCODER_DELAY
:
961 prtd
->initial_samples_drop
= metadata
->value
[0];
962 if (prtd
->next_track_stream_id
) {
963 ret
= q6asm_open_write(prtd
->audio_client
,
964 prtd
->next_track_stream_id
,
967 prtd
->bits_per_sample
,
970 dev_err(component
->dev
, "q6asm_open_write failed\n");
973 ret
= __q6asm_dai_compr_set_codec_params(component
, stream
,
975 prtd
->next_track_stream_id
);
977 dev_err(component
->dev
, "q6asm_open_write failed\n");
981 ret
= q6asm_stream_remove_initial_silence(prtd
->audio_client
,
982 prtd
->next_track_stream_id
,
983 prtd
->initial_samples_drop
);
984 prtd
->next_track_stream_id
= 0;
997 static int q6asm_dai_compr_trigger(struct snd_soc_component
*component
,
998 struct snd_compr_stream
*stream
, int cmd
)
1000 struct snd_compr_runtime
*runtime
= stream
->runtime
;
1001 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
1005 case SNDRV_PCM_TRIGGER_START
:
1006 case SNDRV_PCM_TRIGGER_RESUME
:
1007 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
1008 ret
= q6asm_run_nowait(prtd
->audio_client
, prtd
->stream_id
,
1011 case SNDRV_PCM_TRIGGER_STOP
:
1012 prtd
->state
= Q6ASM_STREAM_STOPPED
;
1013 ret
= q6asm_cmd_nowait(prtd
->audio_client
, prtd
->stream_id
,
1016 case SNDRV_PCM_TRIGGER_SUSPEND
:
1017 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
1018 ret
= q6asm_cmd_nowait(prtd
->audio_client
, prtd
->stream_id
,
1021 case SND_COMPR_TRIGGER_NEXT_TRACK
:
1022 prtd
->next_track
= true;
1023 prtd
->next_track_stream_id
= (prtd
->stream_id
== 1 ? 2 : 1);
1025 case SND_COMPR_TRIGGER_DRAIN
:
1026 case SND_COMPR_TRIGGER_PARTIAL_DRAIN
:
1027 prtd
->notify_on_drain
= true;
1037 static int q6asm_dai_compr_pointer(struct snd_soc_component
*component
,
1038 struct snd_compr_stream
*stream
,
1039 struct snd_compr_tstamp
*tstamp
)
1041 struct snd_compr_runtime
*runtime
= stream
->runtime
;
1042 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
1043 unsigned long flags
;
1045 spin_lock_irqsave(&prtd
->lock
, flags
);
1047 tstamp
->copied_total
= prtd
->copied_total
;
1048 tstamp
->byte_offset
= prtd
->copied_total
% prtd
->pcm_size
;
1050 spin_unlock_irqrestore(&prtd
->lock
, flags
);
1055 static int q6asm_compr_copy(struct snd_soc_component
*component
,
1056 struct snd_compr_stream
*stream
, char __user
*buf
,
1059 struct snd_compr_runtime
*runtime
= stream
->runtime
;
1060 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
1061 unsigned long flags
;
1063 int avail
, bytes_in_flight
= 0;
1069 bytes_received
= prtd
->bytes_received
;
1072 * Make sure that next track data pointer is aligned at 32 bit boundary
1073 * This is a Mandatory requirement from DSP data buffers alignment
1075 if (prtd
->next_track
)
1076 bytes_received
= ALIGN(prtd
->bytes_received
, prtd
->pcm_count
);
1078 app_pointer
= bytes_received
/prtd
->pcm_size
;
1079 app_pointer
= bytes_received
- (app_pointer
* prtd
->pcm_size
);
1080 dstn
= prtd
->dma_buffer
.area
+ app_pointer
;
1082 if (count
< prtd
->pcm_size
- app_pointer
) {
1083 if (copy_from_user(dstn
, buf
, count
))
1086 copy
= prtd
->pcm_size
- app_pointer
;
1087 if (copy_from_user(dstn
, buf
, copy
))
1089 if (copy_from_user(prtd
->dma_buffer
.area
, buf
+ copy
,
1094 spin_lock_irqsave(&prtd
->lock
, flags
);
1096 bytes_in_flight
= prtd
->bytes_received
- prtd
->copied_total
;
1098 if (prtd
->next_track
) {
1099 prtd
->next_track
= false;
1100 prtd
->copied_total
= ALIGN(prtd
->copied_total
, prtd
->pcm_count
);
1101 prtd
->bytes_sent
= ALIGN(prtd
->bytes_sent
, prtd
->pcm_count
);
1104 prtd
->bytes_received
= bytes_received
+ count
;
1106 /* Kick off the data to dsp if its starving!! */
1107 if (prtd
->state
== Q6ASM_STREAM_RUNNING
&& (bytes_in_flight
== 0)) {
1108 uint32_t bytes_to_write
= prtd
->pcm_count
;
1110 avail
= prtd
->bytes_received
- prtd
->bytes_sent
;
1112 if (avail
< prtd
->pcm_count
)
1113 bytes_to_write
= avail
;
1115 q6asm_write_async(prtd
->audio_client
, prtd
->stream_id
,
1116 bytes_to_write
, 0, 0, wflags
);
1117 prtd
->bytes_sent
+= bytes_to_write
;
1120 spin_unlock_irqrestore(&prtd
->lock
, flags
);
1125 static int q6asm_dai_compr_mmap(struct snd_soc_component
*component
,
1126 struct snd_compr_stream
*stream
,
1127 struct vm_area_struct
*vma
)
1129 struct snd_compr_runtime
*runtime
= stream
->runtime
;
1130 struct q6asm_dai_rtd
*prtd
= runtime
->private_data
;
1131 struct device
*dev
= component
->dev
;
1133 return dma_mmap_coherent(dev
, vma
,
1134 prtd
->dma_buffer
.area
, prtd
->dma_buffer
.addr
,
1135 prtd
->dma_buffer
.bytes
);
1138 static int q6asm_dai_compr_get_caps(struct snd_soc_component
*component
,
1139 struct snd_compr_stream
*stream
,
1140 struct snd_compr_caps
*caps
)
1142 caps
->direction
= SND_COMPRESS_PLAYBACK
;
1143 caps
->min_fragment_size
= COMPR_PLAYBACK_MIN_FRAGMENT_SIZE
;
1144 caps
->max_fragment_size
= COMPR_PLAYBACK_MAX_FRAGMENT_SIZE
;
1145 caps
->min_fragments
= COMPR_PLAYBACK_MIN_NUM_FRAGMENTS
;
1146 caps
->max_fragments
= COMPR_PLAYBACK_MAX_NUM_FRAGMENTS
;
1147 caps
->num_codecs
= 5;
1148 caps
->codecs
[0] = SND_AUDIOCODEC_MP3
;
1149 caps
->codecs
[1] = SND_AUDIOCODEC_FLAC
;
1150 caps
->codecs
[2] = SND_AUDIOCODEC_WMA
;
1151 caps
->codecs
[3] = SND_AUDIOCODEC_ALAC
;
1152 caps
->codecs
[4] = SND_AUDIOCODEC_APE
;
1157 static int q6asm_dai_compr_get_codec_caps(struct snd_soc_component
*component
,
1158 struct snd_compr_stream
*stream
,
1159 struct snd_compr_codec_caps
*codec
)
1161 switch (codec
->codec
) {
1162 case SND_AUDIOCODEC_MP3
:
1163 *codec
= q6asm_compr_caps
;
1172 static struct snd_compress_ops q6asm_dai_compress_ops
= {
1173 .open
= q6asm_dai_compr_open
,
1174 .free
= q6asm_dai_compr_free
,
1175 .set_params
= q6asm_dai_compr_set_params
,
1176 .set_metadata
= q6asm_dai_compr_set_metadata
,
1177 .pointer
= q6asm_dai_compr_pointer
,
1178 .trigger
= q6asm_dai_compr_trigger
,
1179 .get_caps
= q6asm_dai_compr_get_caps
,
1180 .get_codec_caps
= q6asm_dai_compr_get_codec_caps
,
1181 .mmap
= q6asm_dai_compr_mmap
,
1182 .copy
= q6asm_compr_copy
,
1185 static int q6asm_dai_pcm_new(struct snd_soc_component
*component
,
1186 struct snd_soc_pcm_runtime
*rtd
)
1188 struct snd_pcm_substream
*psubstream
, *csubstream
;
1189 struct snd_pcm
*pcm
= rtd
->pcm
;
1193 dev
= component
->dev
;
1194 size
= q6asm_dai_hardware_playback
.buffer_bytes_max
;
1195 psubstream
= pcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].substream
;
1197 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dev
, size
,
1198 &psubstream
->dma_buffer
);
1200 dev_err(dev
, "Cannot allocate buffer(s)\n");
1205 csubstream
= pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
;
1207 ret
= snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV
, dev
, size
,
1208 &csubstream
->dma_buffer
);
1210 dev_err(dev
, "Cannot allocate buffer(s)\n");
1212 snd_dma_free_pages(&psubstream
->dma_buffer
);
1220 static void q6asm_dai_pcm_free(struct snd_soc_component
*component
,
1221 struct snd_pcm
*pcm
)
1223 struct snd_pcm_substream
*substream
;
1226 for (i
= 0; i
< ARRAY_SIZE(pcm
->streams
); i
++) {
1227 substream
= pcm
->streams
[i
].substream
;
1229 snd_dma_free_pages(&substream
->dma_buffer
);
1230 substream
->dma_buffer
.area
= NULL
;
1231 substream
->dma_buffer
.addr
= 0;
1236 static const struct snd_soc_component_driver q6asm_fe_dai_component
= {
1238 .open
= q6asm_dai_open
,
1239 .hw_params
= q6asm_dai_hw_params
,
1240 .close
= q6asm_dai_close
,
1241 .prepare
= q6asm_dai_prepare
,
1242 .trigger
= q6asm_dai_trigger
,
1243 .pointer
= q6asm_dai_pointer
,
1244 .mmap
= q6asm_dai_mmap
,
1245 .pcm_construct
= q6asm_dai_pcm_new
,
1246 .pcm_destruct
= q6asm_dai_pcm_free
,
1247 .compress_ops
= &q6asm_dai_compress_ops
,
1250 static struct snd_soc_dai_driver q6asm_fe_dais_template
[] = {
1251 Q6ASM_FEDAI_DRIVER(1),
1252 Q6ASM_FEDAI_DRIVER(2),
1253 Q6ASM_FEDAI_DRIVER(3),
1254 Q6ASM_FEDAI_DRIVER(4),
1255 Q6ASM_FEDAI_DRIVER(5),
1256 Q6ASM_FEDAI_DRIVER(6),
1257 Q6ASM_FEDAI_DRIVER(7),
1258 Q6ASM_FEDAI_DRIVER(8),
1261 static int of_q6asm_parse_dai_data(struct device
*dev
,
1262 struct q6asm_dai_data
*pdata
)
1264 struct snd_soc_dai_driver
*dai_drv
;
1265 struct snd_soc_pcm_stream empty_stream
;
1266 struct device_node
*node
;
1267 int ret
, id
, dir
, idx
= 0;
1270 pdata
->num_dais
= of_get_child_count(dev
->of_node
);
1271 if (!pdata
->num_dais
) {
1272 dev_err(dev
, "No dais found in DT\n");
1276 pdata
->dais
= devm_kcalloc(dev
, pdata
->num_dais
, sizeof(*dai_drv
),
1281 memset(&empty_stream
, 0, sizeof(empty_stream
));
1283 for_each_child_of_node(dev
->of_node
, node
) {
1284 ret
= of_property_read_u32(node
, "reg", &id
);
1285 if (ret
|| id
>= MAX_SESSIONS
|| id
< 0) {
1286 dev_err(dev
, "valid dai id not found:%d\n", ret
);
1290 dai_drv
= &pdata
->dais
[idx
++];
1291 *dai_drv
= q6asm_fe_dais_template
[id
];
1293 ret
= of_property_read_u32(node
, "direction", &dir
);
1297 if (dir
== Q6ASM_DAI_RX
)
1298 dai_drv
->capture
= empty_stream
;
1299 else if (dir
== Q6ASM_DAI_TX
)
1300 dai_drv
->playback
= empty_stream
;
1302 if (of_property_read_bool(node
, "is-compress-dai"))
1303 dai_drv
->compress_new
= snd_soc_new_compress
;
1309 static int q6asm_dai_probe(struct platform_device
*pdev
)
1311 struct device
*dev
= &pdev
->dev
;
1312 struct device_node
*node
= dev
->of_node
;
1313 struct of_phandle_args args
;
1314 struct q6asm_dai_data
*pdata
;
1317 pdata
= devm_kzalloc(dev
, sizeof(*pdata
), GFP_KERNEL
);
1321 rc
= of_parse_phandle_with_fixed_args(node
, "iommus", 1, 0, &args
);
1325 pdata
->sid
= args
.args
[0] & SID_MASK_DEFAULT
;
1327 dev_set_drvdata(dev
, pdata
);
1329 rc
= of_q6asm_parse_dai_data(dev
, pdata
);
1333 return devm_snd_soc_register_component(dev
, &q6asm_fe_dai_component
,
1334 pdata
->dais
, pdata
->num_dais
);
1338 static const struct of_device_id q6asm_dai_device_id
[] = {
1339 { .compatible
= "qcom,q6asm-dais" },
1342 MODULE_DEVICE_TABLE(of
, q6asm_dai_device_id
);
1345 static struct platform_driver q6asm_dai_platform_driver
= {
1347 .name
= "q6asm-dai",
1348 .of_match_table
= of_match_ptr(q6asm_dai_device_id
),
1350 .probe
= q6asm_dai_probe
,
1352 module_platform_driver(q6asm_dai_platform_driver
);
1354 MODULE_DESCRIPTION("Q6ASM dai driver");
1355 MODULE_LICENSE("GPL v2");