Lines Matching +full:q6asm +full:- +full:dais
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
5 #include <dt-bindings/sound/qcom,q6asm.h>
13 #include <sound/soc-dapm.h>
18 #include <linux/dma-mapping.h>
20 #include "q6asm.h"
22 #include "q6dsp-errno.h"
24 #define DRV_NAME "q6asm-fe-dai"
79 struct snd_soc_dai_driver *dais; member
180 struct snd_pcm_substream *substream = prtd->substream; in event_handler()
184 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in event_handler()
185 q6asm_write_async(prtd->audio_client, prtd->stream_id, in event_handler()
186 prtd->pcm_count, 0, 0, 0); in event_handler()
189 prtd->state = Q6ASM_STREAM_STOPPED; in event_handler()
192 prtd->pcm_irq_pos += prtd->pcm_count; in event_handler()
194 if (prtd->state == Q6ASM_STREAM_RUNNING) in event_handler()
195 q6asm_write_async(prtd->audio_client, prtd->stream_id, in event_handler()
196 prtd->pcm_count, 0, 0, 0); in event_handler()
201 prtd->pcm_irq_pos += prtd->pcm_count; in event_handler()
203 if (prtd->state == Q6ASM_STREAM_RUNNING) in event_handler()
204 q6asm_read(prtd->audio_client, prtd->stream_id); in event_handler()
215 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_prepare()
217 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_prepare()
219 struct device *dev = component->dev; in q6asm_dai_prepare()
224 return -EINVAL; in q6asm_dai_prepare()
226 if (!prtd || !prtd->audio_client) { in q6asm_dai_prepare()
229 return -EINVAL; in q6asm_dai_prepare()
232 prtd->pcm_count = snd_pcm_lib_period_bytes(substream); in q6asm_dai_prepare()
233 prtd->pcm_irq_pos = 0; in q6asm_dai_prepare()
235 if (prtd->state) { in q6asm_dai_prepare()
237 q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE); in q6asm_dai_prepare()
238 q6asm_unmap_memory_regions(substream->stream, in q6asm_dai_prepare()
239 prtd->audio_client); in q6asm_dai_prepare()
240 q6routing_stream_close(soc_prtd->dai_link->id, in q6asm_dai_prepare()
241 substream->stream); in q6asm_dai_prepare()
244 ret = q6asm_map_memory_regions(substream->stream, prtd->audio_client, in q6asm_dai_prepare()
245 prtd->phys, in q6asm_dai_prepare()
246 (prtd->pcm_size / prtd->periods), in q6asm_dai_prepare()
247 prtd->periods); in q6asm_dai_prepare()
252 return -ENOMEM; in q6asm_dai_prepare()
255 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in q6asm_dai_prepare()
256 ret = q6asm_open_write(prtd->audio_client, prtd->stream_id, in q6asm_dai_prepare()
258 0, prtd->bits_per_sample, false); in q6asm_dai_prepare()
259 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in q6asm_dai_prepare()
260 ret = q6asm_open_read(prtd->audio_client, prtd->stream_id, in q6asm_dai_prepare()
262 prtd->bits_per_sample); in q6asm_dai_prepare()
270 prtd->session_id = q6asm_get_session_id(prtd->audio_client); in q6asm_dai_prepare()
271 ret = q6routing_stream_open(soc_prtd->dai_link->id, LEGACY_PCM_MODE, in q6asm_dai_prepare()
272 prtd->session_id, substream->stream); in q6asm_dai_prepare()
278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in q6asm_dai_prepare()
280 prtd->audio_client, prtd->stream_id, in q6asm_dai_prepare()
281 runtime->rate, runtime->channels, NULL, in q6asm_dai_prepare()
282 prtd->bits_per_sample); in q6asm_dai_prepare()
283 } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in q6asm_dai_prepare()
284 ret = q6asm_enc_cfg_blk_pcm_format_support(prtd->audio_client, in q6asm_dai_prepare()
285 prtd->stream_id, in q6asm_dai_prepare()
286 runtime->rate, in q6asm_dai_prepare()
287 runtime->channels, in q6asm_dai_prepare()
288 prtd->bits_per_sample); in q6asm_dai_prepare()
291 for (i = 0; i < runtime->periods; i++) in q6asm_dai_prepare()
292 q6asm_read(prtd->audio_client, prtd->stream_id); in q6asm_dai_prepare()
298 prtd->state = Q6ASM_STREAM_RUNNING; in q6asm_dai_prepare()
303 q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE); in q6asm_dai_prepare()
305 q6asm_unmap_memory_regions(substream->stream, prtd->audio_client); in q6asm_dai_prepare()
306 q6asm_audio_client_free(prtd->audio_client); in q6asm_dai_prepare()
307 prtd->audio_client = NULL; in q6asm_dai_prepare()
316 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_trigger()
317 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_trigger()
323 ret = q6asm_run_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_trigger()
327 prtd->state = Q6ASM_STREAM_STOPPED; in q6asm_dai_trigger()
328 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_trigger()
333 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_trigger()
337 ret = -EINVAL; in q6asm_dai_trigger()
347 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_open()
352 struct device *dev = component->dev; in q6asm_dai_open()
356 stream_id = cpu_dai->driver->id; in q6asm_dai_open()
361 return -EINVAL; in q6asm_dai_open()
366 return -ENOMEM; in q6asm_dai_open()
368 prtd->substream = substream; in q6asm_dai_open()
369 prtd->audio_client = q6asm_audio_client_alloc(dev, in q6asm_dai_open()
372 if (IS_ERR(prtd->audio_client)) { in q6asm_dai_open()
374 ret = PTR_ERR(prtd->audio_client); in q6asm_dai_open()
380 prtd->stream_id = 1; in q6asm_dai_open()
382 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in q6asm_dai_open()
383 runtime->hw = q6asm_dai_hardware_playback; in q6asm_dai_open()
384 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in q6asm_dai_open()
385 runtime->hw = q6asm_dai_hardware_capture; in q6asm_dai_open()
393 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in q6asm_dai_open()
417 runtime->private_data = prtd; in q6asm_dai_open()
421 runtime->dma_bytes = q6asm_dai_hardware_playback.buffer_bytes_max; in q6asm_dai_open()
424 if (pdata->sid < 0) in q6asm_dai_open()
425 prtd->phys = substream->dma_buffer.addr; in q6asm_dai_open()
427 prtd->phys = substream->dma_buffer.addr | (pdata->sid << 32); in q6asm_dai_open()
435 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_close()
437 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_close()
439 if (prtd->audio_client) { in q6asm_dai_close()
440 if (prtd->state) in q6asm_dai_close()
441 q6asm_cmd(prtd->audio_client, prtd->stream_id, in q6asm_dai_close()
444 q6asm_unmap_memory_regions(substream->stream, in q6asm_dai_close()
445 prtd->audio_client); in q6asm_dai_close()
446 q6asm_audio_client_free(prtd->audio_client); in q6asm_dai_close()
447 prtd->audio_client = NULL; in q6asm_dai_close()
449 q6routing_stream_close(soc_prtd->dai_link->id, in q6asm_dai_close()
450 substream->stream); in q6asm_dai_close()
459 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_pointer()
460 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_pointer()
462 if (prtd->pcm_irq_pos >= prtd->pcm_size) in q6asm_dai_pointer()
463 prtd->pcm_irq_pos = 0; in q6asm_dai_pointer()
465 return bytes_to_frames(runtime, (prtd->pcm_irq_pos)); in q6asm_dai_pointer()
472 struct snd_pcm_runtime *runtime = substream->runtime; in q6asm_dai_hw_params()
473 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_hw_params()
475 prtd->pcm_size = params_buffer_bytes(params); in q6asm_dai_hw_params()
476 prtd->periods = params_periods(params); in q6asm_dai_hw_params()
480 prtd->bits_per_sample = 16; in q6asm_dai_hw_params()
483 prtd->bits_per_sample = 24; in q6asm_dai_hw_params()
494 struct snd_compr_stream *substream = prtd->cstream; in compress_event_handler()
503 spin_lock_irqsave(&prtd->lock, flags); in compress_event_handler()
504 if (!prtd->bytes_sent) { in compress_event_handler()
505 q6asm_stream_remove_initial_silence(prtd->audio_client, in compress_event_handler()
506 prtd->stream_id, in compress_event_handler()
507 prtd->initial_samples_drop); in compress_event_handler()
509 q6asm_write_async(prtd->audio_client, prtd->stream_id, in compress_event_handler()
510 prtd->pcm_count, 0, 0, 0); in compress_event_handler()
511 prtd->bytes_sent += prtd->pcm_count; in compress_event_handler()
514 spin_unlock_irqrestore(&prtd->lock, flags); in compress_event_handler()
518 spin_lock_irqsave(&prtd->lock, flags); in compress_event_handler()
519 if (prtd->notify_on_drain) { in compress_event_handler()
520 if (substream->partial_drain) { in compress_event_handler()
525 q6asm_cmd_nowait(prtd->audio_client, in compress_event_handler()
526 prtd->stream_id, in compress_event_handler()
532 prtd->stream_id = (prtd->stream_id == 1 ? 2 : 1); in compress_event_handler()
535 snd_compr_drain_notify(prtd->cstream); in compress_event_handler()
536 prtd->notify_on_drain = false; in compress_event_handler()
539 prtd->state = Q6ASM_STREAM_STOPPED; in compress_event_handler()
541 spin_unlock_irqrestore(&prtd->lock, flags); in compress_event_handler()
545 spin_lock_irqsave(&prtd->lock, flags); in compress_event_handler()
548 prtd->copied_total += bytes_written; in compress_event_handler()
551 if (prtd->state != Q6ASM_STREAM_RUNNING) { in compress_event_handler()
552 spin_unlock_irqrestore(&prtd->lock, flags); in compress_event_handler()
556 avail = prtd->bytes_received - prtd->bytes_sent; in compress_event_handler()
557 if (avail > prtd->pcm_count) { in compress_event_handler()
558 bytes_to_write = prtd->pcm_count; in compress_event_handler()
560 if (substream->partial_drain || prtd->notify_on_drain) in compress_event_handler()
566 if (substream->partial_drain && is_last_buffer) { in compress_event_handler()
568 q6asm_stream_remove_trailing_silence(prtd->audio_client, in compress_event_handler()
569 prtd->stream_id, in compress_event_handler()
570 prtd->trailing_samples_drop); in compress_event_handler()
573 q6asm_write_async(prtd->audio_client, prtd->stream_id, in compress_event_handler()
576 prtd->bytes_sent += bytes_to_write; in compress_event_handler()
579 if (prtd->notify_on_drain && is_last_buffer) in compress_event_handler()
580 q6asm_cmd_nowait(prtd->audio_client, in compress_event_handler()
581 prtd->stream_id, CMD_EOS); in compress_event_handler()
583 spin_unlock_irqrestore(&prtd->lock, flags); in compress_event_handler()
594 struct snd_soc_pcm_runtime *rtd = stream->private_data; in q6asm_dai_compr_open()
595 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_open()
598 struct device *dev = component->dev; in q6asm_dai_compr_open()
602 stream_id = cpu_dai->driver->id; in q6asm_dai_compr_open()
606 return -EINVAL; in q6asm_dai_compr_open()
611 return -ENOMEM; in q6asm_dai_compr_open()
614 prtd->stream_id = 1; in q6asm_dai_compr_open()
616 prtd->cstream = stream; in q6asm_dai_compr_open()
617 prtd->audio_client = q6asm_audio_client_alloc(dev, in q6asm_dai_compr_open()
620 if (IS_ERR(prtd->audio_client)) { in q6asm_dai_compr_open()
622 ret = PTR_ERR(prtd->audio_client); in q6asm_dai_compr_open()
629 &prtd->dma_buffer); in q6asm_dai_compr_open()
635 if (pdata->sid < 0) in q6asm_dai_compr_open()
636 prtd->phys = prtd->dma_buffer.addr; in q6asm_dai_compr_open()
638 prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); in q6asm_dai_compr_open()
640 snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); in q6asm_dai_compr_open()
641 spin_lock_init(&prtd->lock); in q6asm_dai_compr_open()
642 runtime->private_data = prtd; in q6asm_dai_compr_open()
647 q6asm_audio_client_free(prtd->audio_client); in q6asm_dai_compr_open()
657 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_free()
658 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_free()
659 struct snd_soc_pcm_runtime *rtd = stream->private_data; in q6asm_dai_compr_free()
661 if (prtd->audio_client) { in q6asm_dai_compr_free()
662 if (prtd->state) { in q6asm_dai_compr_free()
663 q6asm_cmd(prtd->audio_client, prtd->stream_id, in q6asm_dai_compr_free()
665 if (prtd->next_track_stream_id) { in q6asm_dai_compr_free()
666 q6asm_cmd(prtd->audio_client, in q6asm_dai_compr_free()
667 prtd->next_track_stream_id, in q6asm_dai_compr_free()
672 snd_dma_free_pages(&prtd->dma_buffer); in q6asm_dai_compr_free()
673 q6asm_unmap_memory_regions(stream->direction, in q6asm_dai_compr_free()
674 prtd->audio_client); in q6asm_dai_compr_free()
675 q6asm_audio_client_free(prtd->audio_client); in q6asm_dai_compr_free()
676 prtd->audio_client = NULL; in q6asm_dai_compr_free()
678 q6routing_stream_close(rtd->dai_link->id, stream->direction); in q6asm_dai_compr_free()
689 struct snd_compr_runtime *runtime = stream->runtime; in __q6asm_dai_compr_set_codec_params()
690 struct q6asm_dai_rtd *prtd = runtime->private_data; in __q6asm_dai_compr_set_codec_params()
696 struct device *dev = component->dev; in __q6asm_dai_compr_set_codec_params()
704 codec_options = &(prtd->codec.options); in __q6asm_dai_compr_set_codec_params()
706 memcpy(&prtd->codec, codec, sizeof(*codec)); in __q6asm_dai_compr_set_codec_params()
708 switch (codec->id) { in __q6asm_dai_compr_set_codec_params()
712 flac = &codec_options->flac_d; in __q6asm_dai_compr_set_codec_params()
714 flac_cfg.ch_cfg = codec->ch_in; in __q6asm_dai_compr_set_codec_params()
715 flac_cfg.sample_rate = codec->sample_rate; in __q6asm_dai_compr_set_codec_params()
717 flac_cfg.sample_size = flac->sample_size; in __q6asm_dai_compr_set_codec_params()
718 flac_cfg.min_blk_size = flac->min_blk_size; in __q6asm_dai_compr_set_codec_params()
719 flac_cfg.max_blk_size = flac->max_blk_size; in __q6asm_dai_compr_set_codec_params()
720 flac_cfg.max_frame_size = flac->max_frame_size; in __q6asm_dai_compr_set_codec_params()
721 flac_cfg.min_frame_size = flac->min_frame_size; in __q6asm_dai_compr_set_codec_params()
723 ret = q6asm_stream_media_format_block_flac(prtd->audio_client, in __q6asm_dai_compr_set_codec_params()
728 return -EIO; in __q6asm_dai_compr_set_codec_params()
733 wma = &codec_options->wma_d; in __q6asm_dai_compr_set_codec_params()
737 wma_cfg.sample_rate = codec->sample_rate; in __q6asm_dai_compr_set_codec_params()
738 wma_cfg.num_channels = codec->ch_in; in __q6asm_dai_compr_set_codec_params()
739 wma_cfg.bytes_per_sec = codec->bit_rate / 8; in __q6asm_dai_compr_set_codec_params()
740 wma_cfg.block_align = codec->align; in __q6asm_dai_compr_set_codec_params()
741 wma_cfg.bits_per_sample = prtd->bits_per_sample; in __q6asm_dai_compr_set_codec_params()
742 wma_cfg.enc_options = wma->encoder_option; in __q6asm_dai_compr_set_codec_params()
743 wma_cfg.adv_enc_options = wma->adv_encoder_option; in __q6asm_dai_compr_set_codec_params()
744 wma_cfg.adv_enc_options2 = wma->adv_encoder_option2; in __q6asm_dai_compr_set_codec_params()
751 return -EINVAL; in __q6asm_dai_compr_set_codec_params()
754 switch (codec->profile) { in __q6asm_dai_compr_set_codec_params()
778 codec->profile); in __q6asm_dai_compr_set_codec_params()
779 return -EIO; in __q6asm_dai_compr_set_codec_params()
784 prtd->audio_client, stream_id, in __q6asm_dai_compr_set_codec_params()
788 prtd->audio_client, stream_id, in __q6asm_dai_compr_set_codec_params()
792 return -EIO; in __q6asm_dai_compr_set_codec_params()
798 alac = &codec_options->alac_d; in __q6asm_dai_compr_set_codec_params()
800 alac_cfg.sample_rate = codec->sample_rate; in __q6asm_dai_compr_set_codec_params()
801 alac_cfg.avg_bit_rate = codec->bit_rate; in __q6asm_dai_compr_set_codec_params()
802 alac_cfg.bit_depth = prtd->bits_per_sample; in __q6asm_dai_compr_set_codec_params()
803 alac_cfg.num_channels = codec->ch_in; in __q6asm_dai_compr_set_codec_params()
805 alac_cfg.frame_length = alac->frame_length; in __q6asm_dai_compr_set_codec_params()
806 alac_cfg.pb = alac->pb; in __q6asm_dai_compr_set_codec_params()
807 alac_cfg.mb = alac->mb; in __q6asm_dai_compr_set_codec_params()
808 alac_cfg.kb = alac->kb; in __q6asm_dai_compr_set_codec_params()
809 alac_cfg.max_run = alac->max_run; in __q6asm_dai_compr_set_codec_params()
810 alac_cfg.compatible_version = alac->compatible_version; in __q6asm_dai_compr_set_codec_params()
811 alac_cfg.max_frame_bytes = alac->max_frame_bytes; in __q6asm_dai_compr_set_codec_params()
813 switch (codec->ch_in) { in __q6asm_dai_compr_set_codec_params()
821 ret = q6asm_stream_media_format_block_alac(prtd->audio_client, in __q6asm_dai_compr_set_codec_params()
826 return -EIO; in __q6asm_dai_compr_set_codec_params()
832 ape = &codec_options->ape_d; in __q6asm_dai_compr_set_codec_params()
834 ape_cfg.sample_rate = codec->sample_rate; in __q6asm_dai_compr_set_codec_params()
835 ape_cfg.num_channels = codec->ch_in; in __q6asm_dai_compr_set_codec_params()
836 ape_cfg.bits_per_sample = prtd->bits_per_sample; in __q6asm_dai_compr_set_codec_params()
838 ape_cfg.compatible_version = ape->compatible_version; in __q6asm_dai_compr_set_codec_params()
839 ape_cfg.compression_level = ape->compression_level; in __q6asm_dai_compr_set_codec_params()
840 ape_cfg.format_flags = ape->format_flags; in __q6asm_dai_compr_set_codec_params()
841 ape_cfg.blocks_per_frame = ape->blocks_per_frame; in __q6asm_dai_compr_set_codec_params()
842 ape_cfg.final_frame_blocks = ape->final_frame_blocks; in __q6asm_dai_compr_set_codec_params()
843 ape_cfg.total_frames = ape->total_frames; in __q6asm_dai_compr_set_codec_params()
844 ape_cfg.seek_table_present = ape->seek_table_present; in __q6asm_dai_compr_set_codec_params()
846 ret = q6asm_stream_media_format_block_ape(prtd->audio_client, in __q6asm_dai_compr_set_codec_params()
851 return -EIO; in __q6asm_dai_compr_set_codec_params()
866 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_set_params()
867 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_set_params()
868 struct snd_soc_pcm_runtime *rtd = stream->private_data; in q6asm_dai_compr_set_params()
869 int dir = stream->direction; in q6asm_dai_compr_set_params()
871 struct device *dev = component->dev; in q6asm_dai_compr_set_params()
876 return -EINVAL; in q6asm_dai_compr_set_params()
878 if (!prtd || !prtd->audio_client) { in q6asm_dai_compr_set_params()
880 return -EINVAL; in q6asm_dai_compr_set_params()
883 prtd->periods = runtime->fragments; in q6asm_dai_compr_set_params()
884 prtd->pcm_count = runtime->fragment_size; in q6asm_dai_compr_set_params()
885 prtd->pcm_size = runtime->fragments * runtime->fragment_size; in q6asm_dai_compr_set_params()
886 prtd->bits_per_sample = 16; in q6asm_dai_compr_set_params()
889 ret = q6asm_open_write(prtd->audio_client, prtd->stream_id, params->codec.id, in q6asm_dai_compr_set_params()
890 params->codec.profile, prtd->bits_per_sample, in q6asm_dai_compr_set_params()
899 prtd->session_id = q6asm_get_session_id(prtd->audio_client); in q6asm_dai_compr_set_params()
900 ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, in q6asm_dai_compr_set_params()
901 prtd->session_id, dir); in q6asm_dai_compr_set_params()
908 ¶ms->codec, in q6asm_dai_compr_set_params()
909 prtd->stream_id); in q6asm_dai_compr_set_params()
915 ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, in q6asm_dai_compr_set_params()
916 (prtd->pcm_size / prtd->periods), in q6asm_dai_compr_set_params()
917 prtd->periods); in q6asm_dai_compr_set_params()
921 ret = -ENOMEM; in q6asm_dai_compr_set_params()
925 prtd->state = Q6ASM_STREAM_RUNNING; in q6asm_dai_compr_set_params()
930 q6asm_cmd(prtd->audio_client, prtd->stream_id, CMD_CLOSE); in q6asm_dai_compr_set_params()
933 q6asm_audio_client_free(prtd->audio_client); in q6asm_dai_compr_set_params()
934 prtd->audio_client = NULL; in q6asm_dai_compr_set_params()
942 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_set_metadata()
943 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_set_metadata()
946 switch (metadata->key) { in q6asm_dai_compr_set_metadata()
948 prtd->trailing_samples_drop = metadata->value[0]; in q6asm_dai_compr_set_metadata()
951 prtd->initial_samples_drop = metadata->value[0]; in q6asm_dai_compr_set_metadata()
952 if (prtd->next_track_stream_id) { in q6asm_dai_compr_set_metadata()
953 ret = q6asm_open_write(prtd->audio_client, in q6asm_dai_compr_set_metadata()
954 prtd->next_track_stream_id, in q6asm_dai_compr_set_metadata()
955 prtd->codec.id, in q6asm_dai_compr_set_metadata()
956 prtd->codec.profile, in q6asm_dai_compr_set_metadata()
957 prtd->bits_per_sample, in q6asm_dai_compr_set_metadata()
960 dev_err(component->dev, "q6asm_open_write failed\n"); in q6asm_dai_compr_set_metadata()
964 &prtd->codec, in q6asm_dai_compr_set_metadata()
965 prtd->next_track_stream_id); in q6asm_dai_compr_set_metadata()
967 dev_err(component->dev, "q6asm_open_write failed\n"); in q6asm_dai_compr_set_metadata()
971 ret = q6asm_stream_remove_initial_silence(prtd->audio_client, in q6asm_dai_compr_set_metadata()
972 prtd->next_track_stream_id, in q6asm_dai_compr_set_metadata()
973 prtd->initial_samples_drop); in q6asm_dai_compr_set_metadata()
974 prtd->next_track_stream_id = 0; in q6asm_dai_compr_set_metadata()
980 ret = -EINVAL; in q6asm_dai_compr_set_metadata()
990 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_trigger()
991 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_trigger()
998 ret = q6asm_run_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_compr_trigger()
1002 prtd->state = Q6ASM_STREAM_STOPPED; in q6asm_dai_compr_trigger()
1003 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_compr_trigger()
1008 ret = q6asm_cmd_nowait(prtd->audio_client, prtd->stream_id, in q6asm_dai_compr_trigger()
1012 prtd->next_track = true; in q6asm_dai_compr_trigger()
1013 prtd->next_track_stream_id = (prtd->stream_id == 1 ? 2 : 1); in q6asm_dai_compr_trigger()
1017 prtd->notify_on_drain = true; in q6asm_dai_compr_trigger()
1020 ret = -EINVAL; in q6asm_dai_compr_trigger()
1031 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_pointer()
1032 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_pointer()
1035 spin_lock_irqsave(&prtd->lock, flags); in q6asm_dai_compr_pointer()
1037 tstamp->copied_total = prtd->copied_total; in q6asm_dai_compr_pointer()
1038 tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; in q6asm_dai_compr_pointer()
1040 spin_unlock_irqrestore(&prtd->lock, flags); in q6asm_dai_compr_pointer()
1049 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_compr_copy()
1050 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_compr_copy()
1059 bytes_received = prtd->bytes_received; in q6asm_compr_copy()
1065 if (prtd->next_track) in q6asm_compr_copy()
1066 bytes_received = ALIGN(prtd->bytes_received, prtd->pcm_count); in q6asm_compr_copy()
1068 app_pointer = bytes_received/prtd->pcm_size; in q6asm_compr_copy()
1069 app_pointer = bytes_received - (app_pointer * prtd->pcm_size); in q6asm_compr_copy()
1070 dstn = prtd->dma_buffer.area + app_pointer; in q6asm_compr_copy()
1072 if (count < prtd->pcm_size - app_pointer) { in q6asm_compr_copy()
1074 return -EFAULT; in q6asm_compr_copy()
1076 copy = prtd->pcm_size - app_pointer; in q6asm_compr_copy()
1078 return -EFAULT; in q6asm_compr_copy()
1079 if (copy_from_user(prtd->dma_buffer.area, buf + copy, in q6asm_compr_copy()
1080 count - copy)) in q6asm_compr_copy()
1081 return -EFAULT; in q6asm_compr_copy()
1084 spin_lock_irqsave(&prtd->lock, flags); in q6asm_compr_copy()
1086 bytes_in_flight = prtd->bytes_received - prtd->copied_total; in q6asm_compr_copy()
1088 if (prtd->next_track) { in q6asm_compr_copy()
1089 prtd->next_track = false; in q6asm_compr_copy()
1090 prtd->copied_total = ALIGN(prtd->copied_total, prtd->pcm_count); in q6asm_compr_copy()
1091 prtd->bytes_sent = ALIGN(prtd->bytes_sent, prtd->pcm_count); in q6asm_compr_copy()
1094 prtd->bytes_received = bytes_received + count; in q6asm_compr_copy()
1097 if (prtd->state == Q6ASM_STREAM_RUNNING && (bytes_in_flight == 0)) { in q6asm_compr_copy()
1098 uint32_t bytes_to_write = prtd->pcm_count; in q6asm_compr_copy()
1100 avail = prtd->bytes_received - prtd->bytes_sent; in q6asm_compr_copy()
1102 if (avail < prtd->pcm_count) in q6asm_compr_copy()
1105 q6asm_write_async(prtd->audio_client, prtd->stream_id, in q6asm_compr_copy()
1107 prtd->bytes_sent += bytes_to_write; in q6asm_compr_copy()
1110 spin_unlock_irqrestore(&prtd->lock, flags); in q6asm_compr_copy()
1119 struct snd_compr_runtime *runtime = stream->runtime; in q6asm_dai_compr_mmap()
1120 struct q6asm_dai_rtd *prtd = runtime->private_data; in q6asm_dai_compr_mmap()
1121 struct device *dev = component->dev; in q6asm_dai_compr_mmap()
1124 prtd->dma_buffer.area, prtd->dma_buffer.addr, in q6asm_dai_compr_mmap()
1125 prtd->dma_buffer.bytes); in q6asm_dai_compr_mmap()
1132 caps->direction = SND_COMPRESS_PLAYBACK; in q6asm_dai_compr_get_caps()
1133 caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; in q6asm_dai_compr_get_caps()
1134 caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; in q6asm_dai_compr_get_caps()
1135 caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; in q6asm_dai_compr_get_caps()
1136 caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; in q6asm_dai_compr_get_caps()
1137 caps->num_codecs = 5; in q6asm_dai_compr_get_caps()
1138 caps->codecs[0] = SND_AUDIOCODEC_MP3; in q6asm_dai_compr_get_caps()
1139 caps->codecs[1] = SND_AUDIOCODEC_FLAC; in q6asm_dai_compr_get_caps()
1140 caps->codecs[2] = SND_AUDIOCODEC_WMA; in q6asm_dai_compr_get_caps()
1141 caps->codecs[3] = SND_AUDIOCODEC_ALAC; in q6asm_dai_compr_get_caps()
1142 caps->codecs[4] = SND_AUDIOCODEC_APE; in q6asm_dai_compr_get_caps()
1151 switch (codec->codec) { in q6asm_dai_compr_get_codec_caps()
1178 struct snd_pcm *pcm = rtd->pcm; in q6asm_dai_pcm_new()
1182 component->dev, size); in q6asm_dai_pcm_new()
1243 pdata->num_dais = of_get_child_count(dev->of_node); in of_q6asm_parse_dai_data()
1244 if (!pdata->num_dais) { in of_q6asm_parse_dai_data()
1245 dev_err(dev, "No dais found in DT\n"); in of_q6asm_parse_dai_data()
1246 return -EINVAL; in of_q6asm_parse_dai_data()
1249 pdata->dais = devm_kcalloc(dev, pdata->num_dais, sizeof(*dai_drv), in of_q6asm_parse_dai_data()
1251 if (!pdata->dais) in of_q6asm_parse_dai_data()
1252 return -ENOMEM; in of_q6asm_parse_dai_data()
1256 for_each_child_of_node(dev->of_node, node) { in of_q6asm_parse_dai_data()
1263 dai_drv = &pdata->dais[idx++]; in of_q6asm_parse_dai_data()
1271 dai_drv->capture = empty_stream; in of_q6asm_parse_dai_data()
1273 dai_drv->playback = empty_stream; in of_q6asm_parse_dai_data()
1275 if (of_property_read_bool(node, "is-compress-dai")) in of_q6asm_parse_dai_data()
1276 dai_drv->ops = &q6asm_dai_ops; in of_q6asm_parse_dai_data()
1284 struct device *dev = &pdev->dev; in q6asm_dai_probe()
1285 struct device_node *node = dev->of_node; in q6asm_dai_probe()
1292 return -ENOMEM; in q6asm_dai_probe()
1296 pdata->sid = -1; in q6asm_dai_probe()
1298 pdata->sid = args.args[0] & SID_MASK_DEFAULT; in q6asm_dai_probe()
1307 pdata->dais, pdata->num_dais); in q6asm_dai_probe()
1312 { .compatible = "qcom,q6asm-dais" },
1320 .name = "q6asm-dai",
1327 MODULE_DESCRIPTION("Q6ASM dai driver");