Lines Matching +full:dai +full:- +full:sample +full:- +full:format
1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/dma-mapping.h>
60 struct snd_card *card = rtd->card->snd_card;
63 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
67 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, card->dev,
88 struct snd_pcm_runtime *runtime = substream->runtime;
89 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
93 * channels whereas in non-interleaved mode, it uses one QMC channel per
96 prtd->channels = qmc_audio_access_is_interleaved(params_access(params)) ?
99 prtd->substream = substream;
101 prtd->buffer_ended = 0;
102 prtd->buffer_size = params_buffer_size(params);
103 prtd->period_size = params_period_size(params);
105 prtd->ch_dma_addr_start = runtime->dma_addr;
106 prtd->ch_dma_offset = params_buffer_bytes(params) / prtd->channels;
107 prtd->ch_dma_addr_end = runtime->dma_addr + prtd->ch_dma_offset;
108 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
109 prtd->ch_dma_size = params_period_bytes(params) / prtd->channels;
121 for (i = 0; i < prtd->channels; i++) {
122 ret = qmc_chan_write_submit(prtd->qmc_dai->qmc_chans[i],
123 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
124 prtd->ch_dma_size,
125 i == prtd->channels - 1 ? qmc_audio_pcm_write_complete :
128 dev_err(prtd->qmc_dai->dev, "write_submit %u failed %d\n",
141 prtd->buffer_ended += prtd->period_size;
142 if (prtd->buffer_ended >= prtd->buffer_size)
143 prtd->buffer_ended = 0;
145 prtd->ch_dma_addr_current += prtd->ch_dma_size;
146 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
147 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
151 snd_pcm_period_elapsed(prtd->substream);
161 for (i = 0; i < prtd->channels; i++) {
162 ret = qmc_chan_read_submit(prtd->qmc_dai->qmc_chans[i],
163 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset,
164 prtd->ch_dma_size,
165 i == prtd->channels - 1 ? qmc_audio_pcm_read_complete :
168 dev_err(prtd->qmc_dai->dev, "read_submit %u failed %d\n",
181 if (length != prtd->ch_dma_size) {
182 dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n",
183 length, prtd->ch_dma_size);
186 prtd->buffer_ended += prtd->period_size;
187 if (prtd->buffer_ended >= prtd->buffer_size)
188 prtd->buffer_ended = 0;
190 prtd->ch_dma_addr_current += prtd->ch_dma_size;
191 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
192 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
196 snd_pcm_period_elapsed(prtd->substream);
202 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
205 if (!prtd->qmc_dai) {
206 dev_err(component->dev, "qmc_dai is not set\n");
207 return -EINVAL;
212 prtd->buffer_ended = 0;
213 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
222 prtd->ch_dma_addr_current += prtd->ch_dma_size;
223 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
224 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
237 prtd->ch_dma_addr_current += prtd->ch_dma_size;
238 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end)
239 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start;
258 return -EINVAL;
267 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
269 return prtd->buffer_ended;
276 struct qmc_audio *qmc_audio = dev_get_drvdata(component->dev);
278 int id = args->args[0];
281 for (i = 0; i < qmc_audio->num_dais; i++) {
282 dai_driver = qmc_audio->dai_drivers + i;
283 if (dai_driver->id == id) {
284 *dai_name = dai_driver->name;
289 return -EINVAL;
308 struct snd_pcm_runtime *runtime = substream->runtime;
321 return -ENOMEM;
323 runtime->private_data = prtd;
331 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
347 static unsigned int qmc_dai_get_index(struct snd_soc_dai *dai)
349 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
351 return dai->driver - qmc_audio->dai_drivers;
354 static struct qmc_dai *qmc_dai_get_data(struct snd_soc_dai *dai)
356 struct qmc_audio *qmc_audio = snd_soc_dai_get_drvdata(dai);
359 index = qmc_dai_get_index(dai);
360 if (index > qmc_audio->num_dais)
363 return qmc_audio->dais + index;
367 * The constraints for format/channel is to match with the number of 8bit
368 * time-slots available.
375 snd_pcm_format_t format = params_format(params);
378 switch (snd_pcm_format_physical_width(format)) {
392 dev_err(qmc_dai->dev, "format physical width %u not supported\n",
393 snd_pcm_format_physical_width(format));
394 return -EINVAL;
405 struct qmc_dai *qmc_dai = rule->private;
407 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_tx_ts);
413 struct qmc_dai *qmc_dai = rule->private;
415 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_rx_ts);
425 snd_pcm_format_t format;
429 dev_err(qmc_dai->dev, "channels %u not supported\n",
431 return -EINVAL;
437 pcm_for_each_format(format) {
438 if (snd_mask_test_format(f_old, format)) {
439 if (snd_pcm_format_physical_width(format) <= slot_width)
440 snd_mask_set_format(&f_new, format);
450 struct qmc_dai *qmc_dai = rule->private;
452 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_tx_ts);
458 struct qmc_dai *qmc_dai = rule->private;
460 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_rx_ts);
472 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
475 frame_bits = qmc_dai->nb_rx_ts * 8;
479 frame_bits = qmc_dai->nb_tx_ts * 8;
482 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
484 SNDRV_PCM_HW_PARAM_FORMAT, -1);
486 dev_err(qmc_dai->dev, "Failed to add channels rule (%d)\n", ret);
490 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT,
492 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
494 dev_err(qmc_dai->dev, "Failed to add format rule (%d)\n", ret);
498 ret = snd_pcm_hw_constraint_single(substream->runtime,
502 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
508 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
511 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
525 frame_bits = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ?
526 qmc_dai->nb_rx_ts * 8 : qmc_dai->nb_tx_ts * 8;
527 ret = snd_pcm_hw_constraint_single(substream->runtime,
531 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret);
537 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS,
540 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret);
548 struct snd_soc_dai *dai)
550 struct qmc_dai_prtd *prtd = substream->runtime->private_data;
553 qmc_dai = qmc_dai_get_data(dai);
555 dev_err(dai->dev, "Invalid dai\n");
556 return -EINVAL;
559 prtd->qmc_dai = qmc_dai;
561 return qmc_dai->nb_chans_avail > 1 ?
568 struct snd_soc_dai *dai)
576 qmc_dai = qmc_dai_get_data(dai);
578 dev_err(dai->dev, "Invalid dai\n");
579 return -EINVAL;
584 * channels whereas in non-interleaved mode, it uses one QMC channel per
590 if (nb_chans_used > qmc_dai->nb_chans_avail) {
591 dev_err(dai->dev, "Not enough qmc_chans. Need %u, avail %u\n",
592 nb_chans_used, qmc_dai->nb_chans_avail);
593 return -EINVAL;
596 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
600 ret = qmc_chan_set_param(qmc_dai->qmc_chans[i], &chan_param);
602 dev_err(dai->dev, "qmc_chans[%u], set param failed %d\n",
607 qmc_dai->nb_chans_used_rx = nb_chans_used;
609 qmc_dai->nb_chans_used_tx = nb_chans_used;
616 struct snd_soc_dai *dai)
625 qmc_dai = qmc_dai_get_data(dai);
627 dev_err(dai->dev, "Invalid dai\n");
628 return -EINVAL;
631 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
633 nb_chans_used = qmc_dai->nb_chans_used_tx;
636 nb_chans_used = qmc_dai->nb_chans_used_rx;
644 ret = qmc_chan_start(qmc_dai->qmc_chans[i], direction);
653 ret_tmp = qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
659 ret_tmp = qmc_chan_reset(qmc_dai->qmc_chans[i], direction);
671 ret_tmp = qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
680 return -EINVAL;
686 while (i--) {
687 qmc_chan_stop(qmc_dai->qmc_chans[i], direction);
688 qmc_chan_reset(qmc_dai->qmc_chans[i], direction);
703 snd_pcm_format_t format;
711 pcm_for_each_format(format) {
713 * Support format other than little-endian (ie big-endian or
716 if (snd_pcm_format_little_endian(format) == 1)
720 format_width = snd_pcm_format_physical_width(format);
738 formats_mask |= pcm_format_to_bits(format);
762 qmc_dai->dev = qmc_audio->dev;
766 dev_err(qmc_audio->dev, "%pOF: failed to read reg\n", np);
769 qmc_dai->id = val;
771 qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d",
772 np->parent->name, qmc_dai->id);
773 if (!qmc_dai->name)
774 return -ENOMEM;
776 count = qmc_chan_count_phandles(np, "fsl,qmc-chan");
778 return dev_err_probe(qmc_audio->dev, count,
779 "dai %d get number of QMC channel failed\n", qmc_dai->id);
781 return dev_err_probe(qmc_audio->dev, -EINVAL,
782 "dai %d no QMC channel defined\n", qmc_dai->id);
784 qmc_dai->qmc_chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->qmc_chans),
786 if (!qmc_dai->qmc_chans)
787 return -ENOMEM;
790 qmc_dai->qmc_chans[i] = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np,
791 "fsl,qmc-chan", i);
792 if (IS_ERR(qmc_dai->qmc_chans[i])) {
793 return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->qmc_chans[i]),
794 "dai %d get QMC channel %d failed\n", qmc_dai->id, i);
797 ret = qmc_chan_get_info(qmc_dai->qmc_chans[i], &info);
799 dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n",
800 qmc_dai->id, i, ret);
805 dev_err(qmc_audio->dev, "dai %d QMC chan %d mode %d is not QMC_TRANSPARENT\n",
806 qmc_dai->id, i, info.mode);
807 return -EINVAL;
821 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Tx timeslots (%u instead of %u)\n",
822 qmc_dai->id, i, info.nb_tx_ts, nb_tx_ts);
823 return -EINVAL;
826 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Rx timeslots (%u instead of %u)\n",
827 qmc_dai->id, i, info.nb_rx_ts, nb_rx_ts);
828 return -EINVAL;
831 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Tx frame sample rate (%lu instead of %lu)\n",
832 qmc_dai->id, i, info.tx_fs_rate, tx_fs_rate);
833 return -EINVAL;
836 dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Rx frame sample rate (%lu instead of %lu)\n",
837 qmc_dai->id, i, info.rx_fs_rate, rx_fs_rate);
838 return -EINVAL;
842 ret = qmc_chan_get_ts_info(qmc_dai->qmc_chans[i], &ts_info);
844 dev_err(qmc_audio->dev, "dai %d get QMC %d channel TS info failed %d\n",
845 qmc_dai->id, i, ret);
853 dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (RX timeslot %d before %d)\n",
854 qmc_dai->id, i, prev_last_rx_ts, last_rx_ts);
855 return -EINVAL;
858 dev_err(qmc_audio->dev, "dai %d QMC chan %d unordered channels (TX timeslot %d before %d)\n",
859 qmc_dai->id, i, prev_last_tx_ts, last_tx_ts);
860 return -EINVAL;
867 qmc_dai->nb_chans_avail = count;
868 qmc_dai->nb_tx_ts = nb_tx_ts * count;
869 qmc_dai->nb_rx_ts = nb_rx_ts * count;
871 qmc_soc_dai_driver->id = qmc_dai->id;
872 qmc_soc_dai_driver->name = qmc_dai->name;
874 qmc_soc_dai_driver->playback.channels_min = 0;
875 qmc_soc_dai_driver->playback.channels_max = 0;
877 qmc_soc_dai_driver->playback.channels_min = 1;
878 qmc_soc_dai_driver->playback.channels_max = count > 1 ? count : nb_tx_ts;
880 qmc_soc_dai_driver->playback.formats = qmc_audio_formats(nb_tx_ts,
883 qmc_soc_dai_driver->capture.channels_min = 0;
884 qmc_soc_dai_driver->capture.channels_max = 0;
886 qmc_soc_dai_driver->capture.channels_min = 1;
887 qmc_soc_dai_driver->capture.channels_max = count > 1 ? count : nb_rx_ts;
889 qmc_soc_dai_driver->capture.formats = qmc_audio_formats(nb_rx_ts,
892 qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(tx_fs_rate);
893 qmc_soc_dai_driver->playback.rate_min = tx_fs_rate;
894 qmc_soc_dai_driver->playback.rate_max = tx_fs_rate;
895 qmc_soc_dai_driver->capture.rates = snd_pcm_rate_to_rate_bit(rx_fs_rate);
896 qmc_soc_dai_driver->capture.rate_min = rx_fs_rate;
897 qmc_soc_dai_driver->capture.rate_max = rx_fs_rate;
899 qmc_soc_dai_driver->ops = &qmc_dai_ops;
906 struct device_node *np = pdev->dev.of_node;
912 qmc_audio = devm_kzalloc(&pdev->dev, sizeof(*qmc_audio), GFP_KERNEL);
914 return -ENOMEM;
916 qmc_audio->dev = &pdev->dev;
918 qmc_audio->num_dais = of_get_available_child_count(np);
919 if (qmc_audio->num_dais) {
920 qmc_audio->dais = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
921 sizeof(*qmc_audio->dais),
923 if (!qmc_audio->dais)
924 return -ENOMEM;
926 qmc_audio->dai_drivers = devm_kcalloc(&pdev->dev, qmc_audio->num_dais,
927 sizeof(*qmc_audio->dai_drivers),
929 if (!qmc_audio->dai_drivers)
930 return -ENOMEM;
936 qmc_audio->dais + i,
937 qmc_audio->dai_drivers + i);
947 ret = devm_snd_soc_register_component(qmc_audio->dev,
949 qmc_audio->dai_drivers,
950 qmc_audio->num_dais);
958 { .compatible = "fsl,qmc-audio" },
965 .name = "fsl-qmc-audio",