Lines Matching +full:qmc +full:- +full:chan
1 // SPDX-License-Identifier: GPL-2.0
3 * ALSA SoC using the QUICC Multichannel Controller (QMC)
10 #include <linux/dma-mapping.h>
16 #include <soc/fsl/qe/qmc.h>
67 struct snd_card *card = rtd->card->snd_card; in qmc_audio_pcm_construct()
70 ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); in qmc_audio_pcm_construct()
74 snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, card->dev, in qmc_audio_pcm_construct()
95 struct snd_pcm_runtime *runtime = substream->runtime; in qmc_audio_pcm_hw_params()
96 struct qmc_dai_prtd *prtd = substream->runtime->private_data; in qmc_audio_pcm_hw_params()
99 * In interleaved mode, the driver uses one QMC channel for all audio in qmc_audio_pcm_hw_params()
100 * channels whereas in non-interleaved mode, it uses one QMC channel per in qmc_audio_pcm_hw_params()
103 prtd->channels = qmc_audio_access_is_interleaved(params_access(params)) ? in qmc_audio_pcm_hw_params()
106 prtd->substream = substream; in qmc_audio_pcm_hw_params()
108 prtd->buffer_ended = 0; in qmc_audio_pcm_hw_params()
109 prtd->buffer_size = params_buffer_size(params); in qmc_audio_pcm_hw_params()
110 prtd->period_size = params_period_size(params); in qmc_audio_pcm_hw_params()
112 prtd->ch_dma_addr_start = runtime->dma_addr; in qmc_audio_pcm_hw_params()
113 prtd->ch_dma_offset = params_buffer_bytes(params) / prtd->channels; in qmc_audio_pcm_hw_params()
114 prtd->ch_dma_addr_end = runtime->dma_addr + prtd->ch_dma_offset; in qmc_audio_pcm_hw_params()
115 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; in qmc_audio_pcm_hw_params()
116 prtd->ch_dma_size = params_period_bytes(params) / prtd->channels; in qmc_audio_pcm_hw_params()
128 for (i = 0; i < prtd->channels; i++) { in qmc_audio_pcm_write_submit()
129 bitmap_set(prtd->chans_pending, i, 1); in qmc_audio_pcm_write_submit()
131 ret = qmc_chan_write_submit(prtd->qmc_dai->chans[i].qmc_chan, in qmc_audio_pcm_write_submit()
132 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, in qmc_audio_pcm_write_submit()
133 prtd->ch_dma_size, in qmc_audio_pcm_write_submit()
135 &prtd->qmc_dai->chans[i]); in qmc_audio_pcm_write_submit()
137 dev_err(prtd->qmc_dai->dev, "write_submit %u failed %d\n", in qmc_audio_pcm_write_submit()
139 bitmap_clear(prtd->chans_pending, i, 1); in qmc_audio_pcm_write_submit()
149 struct qmc_dai_chan *chan = context; in qmc_audio_pcm_write_complete() local
152 prtd = chan->prtd_tx; in qmc_audio_pcm_write_complete()
155 bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1); in qmc_audio_pcm_write_complete()
158 * All QMC channels involved must have completed their transfer before in qmc_audio_pcm_write_complete()
161 if (!bitmap_empty(prtd->chans_pending, 64)) in qmc_audio_pcm_write_complete()
164 prtd->buffer_ended += prtd->period_size; in qmc_audio_pcm_write_complete()
165 if (prtd->buffer_ended >= prtd->buffer_size) in qmc_audio_pcm_write_complete()
166 prtd->buffer_ended = 0; in qmc_audio_pcm_write_complete()
168 prtd->ch_dma_addr_current += prtd->ch_dma_size; in qmc_audio_pcm_write_complete()
169 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) in qmc_audio_pcm_write_complete()
170 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; in qmc_audio_pcm_write_complete()
174 snd_pcm_period_elapsed(prtd->substream); in qmc_audio_pcm_write_complete()
184 for (i = 0; i < prtd->channels; i++) { in qmc_audio_pcm_read_submit()
185 bitmap_set(prtd->chans_pending, i, 1); in qmc_audio_pcm_read_submit()
187 ret = qmc_chan_read_submit(prtd->qmc_dai->chans[i].qmc_chan, in qmc_audio_pcm_read_submit()
188 prtd->ch_dma_addr_current + i * prtd->ch_dma_offset, in qmc_audio_pcm_read_submit()
189 prtd->ch_dma_size, in qmc_audio_pcm_read_submit()
191 &prtd->qmc_dai->chans[i]); in qmc_audio_pcm_read_submit()
193 dev_err(prtd->qmc_dai->dev, "read_submit %u failed %d\n", in qmc_audio_pcm_read_submit()
195 bitmap_clear(prtd->chans_pending, i, 1); in qmc_audio_pcm_read_submit()
205 struct qmc_dai_chan *chan = context; in qmc_audio_pcm_read_complete() local
208 prtd = chan->prtd_rx; in qmc_audio_pcm_read_complete()
211 bitmap_clear(prtd->chans_pending, chan - prtd->qmc_dai->chans, 1); in qmc_audio_pcm_read_complete()
213 if (length != prtd->ch_dma_size) { in qmc_audio_pcm_read_complete()
214 dev_err(prtd->qmc_dai->dev, "read complete length = %zu, exp %zu\n", in qmc_audio_pcm_read_complete()
215 length, prtd->ch_dma_size); in qmc_audio_pcm_read_complete()
219 * All QMC channels involved must have completed their transfer before in qmc_audio_pcm_read_complete()
222 if (!bitmap_empty(prtd->chans_pending, 64)) in qmc_audio_pcm_read_complete()
225 prtd->buffer_ended += prtd->period_size; in qmc_audio_pcm_read_complete()
226 if (prtd->buffer_ended >= prtd->buffer_size) in qmc_audio_pcm_read_complete()
227 prtd->buffer_ended = 0; in qmc_audio_pcm_read_complete()
229 prtd->ch_dma_addr_current += prtd->ch_dma_size; in qmc_audio_pcm_read_complete()
230 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) in qmc_audio_pcm_read_complete()
231 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; in qmc_audio_pcm_read_complete()
235 snd_pcm_period_elapsed(prtd->substream); in qmc_audio_pcm_read_complete()
241 struct qmc_dai_prtd *prtd = substream->runtime->private_data; in qmc_audio_pcm_trigger()
245 if (!prtd->qmc_dai) { in qmc_audio_pcm_trigger()
246 dev_err(component->dev, "qmc_dai is not set\n"); in qmc_audio_pcm_trigger()
247 return -EINVAL; in qmc_audio_pcm_trigger()
252 bitmap_zero(prtd->chans_pending, 64); in qmc_audio_pcm_trigger()
253 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in qmc_audio_pcm_trigger()
254 for (i = 0; i < prtd->channels; i++) in qmc_audio_pcm_trigger()
255 prtd->qmc_dai->chans[i].prtd_tx = prtd; in qmc_audio_pcm_trigger()
263 prtd->ch_dma_addr_current += prtd->ch_dma_size; in qmc_audio_pcm_trigger()
264 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) in qmc_audio_pcm_trigger()
265 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; in qmc_audio_pcm_trigger()
272 for (i = 0; i < prtd->channels; i++) in qmc_audio_pcm_trigger()
273 prtd->qmc_dai->chans[i].prtd_rx = prtd; in qmc_audio_pcm_trigger()
281 prtd->ch_dma_addr_current += prtd->ch_dma_size; in qmc_audio_pcm_trigger()
282 if (prtd->ch_dma_addr_current >= prtd->ch_dma_addr_end) in qmc_audio_pcm_trigger()
283 prtd->ch_dma_addr_current = prtd->ch_dma_addr_start; in qmc_audio_pcm_trigger()
302 return -EINVAL; in qmc_audio_pcm_trigger()
311 struct qmc_dai_prtd *prtd = substream->runtime->private_data; in qmc_audio_pcm_pointer()
313 return prtd->buffer_ended; in qmc_audio_pcm_pointer()
320 struct qmc_audio *qmc_audio = dev_get_drvdata(component->dev); in qmc_audio_of_xlate_dai_name()
322 int id = args->args[0]; in qmc_audio_of_xlate_dai_name()
325 for (i = 0; i < qmc_audio->num_dais; i++) { in qmc_audio_of_xlate_dai_name()
326 dai_driver = qmc_audio->dai_drivers + i; in qmc_audio_of_xlate_dai_name()
327 if (dai_driver->id == id) { in qmc_audio_of_xlate_dai_name()
328 *dai_name = dai_driver->name; in qmc_audio_of_xlate_dai_name()
333 return -EINVAL; in qmc_audio_of_xlate_dai_name()
352 struct snd_pcm_runtime *runtime = substream->runtime; in qmc_audio_pcm_open()
365 return -ENOMEM; in qmc_audio_pcm_open()
367 runtime->private_data = prtd; in qmc_audio_pcm_open()
375 struct qmc_dai_prtd *prtd = substream->runtime->private_data; in qmc_audio_pcm_close()
395 return dai->driver - qmc_audio->dai_drivers; in qmc_dai_get_index()
404 if (index > qmc_audio->num_dais) in qmc_dai_get_data()
407 return qmc_audio->dais + index; in qmc_dai_get_data()
412 * time-slots available.
436 dev_err(qmc_dai->dev, "format physical width %u not supported\n", in qmc_dai_hw_rule_channels_by_format()
438 return -EINVAL; in qmc_dai_hw_rule_channels_by_format()
449 struct qmc_dai *qmc_dai = rule->private; in qmc_dai_hw_rule_playback_channels_by_format()
451 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_tx_ts); in qmc_dai_hw_rule_playback_channels_by_format()
457 struct qmc_dai *qmc_dai = rule->private; in qmc_dai_hw_rule_capture_channels_by_format()
459 return qmc_dai_hw_rule_channels_by_format(qmc_dai, params, qmc_dai->nb_rx_ts); in qmc_dai_hw_rule_capture_channels_by_format()
473 dev_err(qmc_dai->dev, "channels %u not supported\n", in qmc_dai_hw_rule_format_by_channels()
475 return -EINVAL; in qmc_dai_hw_rule_format_by_channels()
494 struct qmc_dai *qmc_dai = rule->private; in qmc_dai_hw_rule_playback_format_by_channels()
496 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_tx_ts); in qmc_dai_hw_rule_playback_format_by_channels()
502 struct qmc_dai *qmc_dai = rule->private; in qmc_dai_hw_rule_capture_format_by_channels()
504 return qmc_dai_hw_rule_format_by_channels(qmc_dai, params, qmc_dai->nb_rx_ts); in qmc_dai_hw_rule_capture_format_by_channels()
516 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in qmc_dai_constraints_interleaved()
519 frame_bits = qmc_dai->nb_rx_ts * 8; in qmc_dai_constraints_interleaved()
523 frame_bits = qmc_dai->nb_tx_ts * 8; in qmc_dai_constraints_interleaved()
526 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, in qmc_dai_constraints_interleaved()
528 SNDRV_PCM_HW_PARAM_FORMAT, -1); in qmc_dai_constraints_interleaved()
530 dev_err(qmc_dai->dev, "Failed to add channels rule (%d)\n", ret); in qmc_dai_constraints_interleaved()
534 ret = snd_pcm_hw_rule_add(substream->runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, in qmc_dai_constraints_interleaved()
536 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in qmc_dai_constraints_interleaved()
538 dev_err(qmc_dai->dev, "Failed to add format rule (%d)\n", ret); in qmc_dai_constraints_interleaved()
542 ret = snd_pcm_hw_constraint_single(substream->runtime, in qmc_dai_constraints_interleaved()
546 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret); in qmc_dai_constraints_interleaved()
552 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS, in qmc_dai_constraints_interleaved()
555 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret); in qmc_dai_constraints_interleaved()
569 frame_bits = (substream->stream == SNDRV_PCM_STREAM_CAPTURE) ? in qmc_dai_constraints_noninterleaved()
570 qmc_dai->nb_rx_ts * 8 : qmc_dai->nb_tx_ts * 8; in qmc_dai_constraints_noninterleaved()
571 ret = snd_pcm_hw_constraint_single(substream->runtime, in qmc_dai_constraints_noninterleaved()
575 dev_err(qmc_dai->dev, "Failed to add frame_bits constraint (%d)\n", ret); in qmc_dai_constraints_noninterleaved()
581 ret = snd_pcm_hw_constraint_mask64(substream->runtime, SNDRV_PCM_HW_PARAM_ACCESS, in qmc_dai_constraints_noninterleaved()
584 dev_err(qmc_dai->dev, "Failed to add hw_param_access constraint (%d)\n", ret); in qmc_dai_constraints_noninterleaved()
594 struct qmc_dai_prtd *prtd = substream->runtime->private_data; in qmc_dai_startup()
599 dev_err(dai->dev, "Invalid dai\n"); in qmc_dai_startup()
600 return -EINVAL; in qmc_dai_startup()
603 prtd->qmc_dai = qmc_dai; in qmc_dai_startup()
605 return qmc_dai->nb_chans_avail > 1 ? in qmc_dai_startup()
622 dev_err(dai->dev, "Invalid dai\n"); in qmc_dai_hw_params()
623 return -EINVAL; in qmc_dai_hw_params()
627 * In interleaved mode, the driver uses one QMC channel for all audio in qmc_dai_hw_params()
628 * channels whereas in non-interleaved mode, it uses one QMC channel per in qmc_dai_hw_params()
634 if (nb_chans_used > qmc_dai->nb_chans_avail) { in qmc_dai_hw_params()
635 dev_err(dai->dev, "Not enough qmc_chans. Need %u, avail %u\n", in qmc_dai_hw_params()
636 nb_chans_used, qmc_dai->nb_chans_avail); in qmc_dai_hw_params()
637 return -EINVAL; in qmc_dai_hw_params()
640 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in qmc_dai_hw_params()
644 ret = qmc_chan_set_param(qmc_dai->chans[i].qmc_chan, &chan_param); in qmc_dai_hw_params()
646 dev_err(dai->dev, "chans[%u], set param failed %d\n", in qmc_dai_hw_params()
651 qmc_dai->nb_chans_used_rx = nb_chans_used; in qmc_dai_hw_params()
653 qmc_dai->nb_chans_used_tx = nb_chans_used; in qmc_dai_hw_params()
671 dev_err(dai->dev, "Invalid dai\n"); in qmc_dai_trigger()
672 return -EINVAL; in qmc_dai_trigger()
675 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in qmc_dai_trigger()
677 nb_chans_used = qmc_dai->nb_chans_used_tx; in qmc_dai_trigger()
680 nb_chans_used = qmc_dai->nb_chans_used_rx; in qmc_dai_trigger()
688 ret = qmc_chan_start(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
695 /* Stop and reset all QMC channels and return the first error encountered */ in qmc_dai_trigger()
697 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
703 ret_tmp = qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
713 /* Stop all QMC channels and return the first error encountered */ in qmc_dai_trigger()
715 ret_tmp = qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
724 return -EINVAL; in qmc_dai_trigger()
730 while (i--) { in qmc_dai_trigger()
731 qmc_chan_stop(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
732 qmc_chan_reset(qmc_dai->chans[i].qmc_chan, direction); in qmc_dai_trigger()
757 * Support format other than little-endian (ie big-endian or in qmc_audio_formats()
801 qmc_dai->dev = qmc_audio->dev; in qmc_audio_dai_parse()
805 dev_err(qmc_audio->dev, "%pOF: failed to read reg\n", np); in qmc_audio_dai_parse()
808 qmc_dai->id = val; in qmc_audio_dai_parse()
810 qmc_dai->name = devm_kasprintf(qmc_audio->dev, GFP_KERNEL, "%s.%d", in qmc_audio_dai_parse()
811 np->parent->name, qmc_dai->id); in qmc_audio_dai_parse()
812 if (!qmc_dai->name) in qmc_audio_dai_parse()
813 return -ENOMEM; in qmc_audio_dai_parse()
815 count = qmc_chan_count_phandles(np, "fsl,qmc-chan"); in qmc_audio_dai_parse()
817 return dev_err_probe(qmc_audio->dev, count, in qmc_audio_dai_parse()
818 "dai %d get number of QMC channel failed\n", qmc_dai->id); in qmc_audio_dai_parse()
820 return dev_err_probe(qmc_audio->dev, -EINVAL, in qmc_audio_dai_parse()
821 "dai %d no QMC channel defined\n", qmc_dai->id); in qmc_audio_dai_parse()
823 qmc_dai->chans = devm_kcalloc(qmc_audio->dev, count, sizeof(*qmc_dai->chans), GFP_KERNEL); in qmc_audio_dai_parse()
824 if (!qmc_dai->chans) in qmc_audio_dai_parse()
825 return -ENOMEM; in qmc_audio_dai_parse()
828 qmc_dai->chans[i].qmc_chan = devm_qmc_chan_get_byphandles_index(qmc_audio->dev, np, in qmc_audio_dai_parse()
829 "fsl,qmc-chan", i); in qmc_audio_dai_parse()
830 if (IS_ERR(qmc_dai->chans[i].qmc_chan)) { in qmc_audio_dai_parse()
831 return dev_err_probe(qmc_audio->dev, PTR_ERR(qmc_dai->chans[i].qmc_chan), in qmc_audio_dai_parse()
832 "dai %d get QMC channel %d failed\n", qmc_dai->id, i); in qmc_audio_dai_parse()
835 ret = qmc_chan_get_info(qmc_dai->chans[i].qmc_chan, &info); in qmc_audio_dai_parse()
837 dev_err(qmc_audio->dev, "dai %d get QMC %d channel info failed %d\n", in qmc_audio_dai_parse()
838 qmc_dai->id, i, ret); in qmc_audio_dai_parse()
841 dev_info(qmc_audio->dev, "dai %d QMC channel %d mode %d, nb_tx_ts %u, nb_rx_ts %u\n", in qmc_audio_dai_parse()
842 qmc_dai->id, i, info.mode, info.nb_tx_ts, info.nb_rx_ts); in qmc_audio_dai_parse()
845 dev_err(qmc_audio->dev, "dai %d QMC chan %d mode %d is not QMC_TRANSPARENT\n", in qmc_audio_dai_parse()
846 qmc_dai->id, i, info.mode); in qmc_audio_dai_parse()
847 return -EINVAL; in qmc_audio_dai_parse()
861 …dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Tx timeslots (%u instead of %u)… in qmc_audio_dai_parse()
862 qmc_dai->id, i, info.nb_tx_ts, nb_tx_ts); in qmc_audio_dai_parse()
863 return -EINVAL; in qmc_audio_dai_parse()
866 …dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent number of Rx timeslots (%u instead of %u)… in qmc_audio_dai_parse()
867 qmc_dai->id, i, info.nb_rx_ts, nb_rx_ts); in qmc_audio_dai_parse()
868 return -EINVAL; in qmc_audio_dai_parse()
871 …dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Tx frame sample rate (%lu instead of %lu)… in qmc_audio_dai_parse()
872 qmc_dai->id, i, info.tx_fs_rate, tx_fs_rate); in qmc_audio_dai_parse()
873 return -EINVAL; in qmc_audio_dai_parse()
876 …dev_err(qmc_audio->dev, "dai %d QMC chan %d inconsistent Rx frame sample rate (%lu instead of %lu)… in qmc_audio_dai_parse()
877 qmc_dai->id, i, info.rx_fs_rate, rx_fs_rate); in qmc_audio_dai_parse()
878 return -EINVAL; in qmc_audio_dai_parse()
883 qmc_dai->nb_chans_avail = count; in qmc_audio_dai_parse()
884 qmc_dai->nb_tx_ts = nb_tx_ts * count; in qmc_audio_dai_parse()
885 qmc_dai->nb_rx_ts = nb_rx_ts * count; in qmc_audio_dai_parse()
887 qmc_soc_dai_driver->id = qmc_dai->id; in qmc_audio_dai_parse()
888 qmc_soc_dai_driver->name = qmc_dai->name; in qmc_audio_dai_parse()
890 qmc_soc_dai_driver->playback.channels_min = 0; in qmc_audio_dai_parse()
891 qmc_soc_dai_driver->playback.channels_max = 0; in qmc_audio_dai_parse()
893 qmc_soc_dai_driver->playback.channels_min = 1; in qmc_audio_dai_parse()
894 qmc_soc_dai_driver->playback.channels_max = count > 1 ? count : nb_tx_ts; in qmc_audio_dai_parse()
896 qmc_soc_dai_driver->playback.formats = qmc_audio_formats(nb_tx_ts, in qmc_audio_dai_parse()
899 qmc_soc_dai_driver->capture.channels_min = 0; in qmc_audio_dai_parse()
900 qmc_soc_dai_driver->capture.channels_max = 0; in qmc_audio_dai_parse()
902 qmc_soc_dai_driver->capture.channels_min = 1; in qmc_audio_dai_parse()
903 qmc_soc_dai_driver->capture.channels_max = count > 1 ? count : nb_rx_ts; in qmc_audio_dai_parse()
905 qmc_soc_dai_driver->capture.formats = qmc_audio_formats(nb_rx_ts, in qmc_audio_dai_parse()
908 qmc_soc_dai_driver->playback.rates = snd_pcm_rate_to_rate_bit(tx_fs_rate); in qmc_audio_dai_parse()
909 qmc_soc_dai_driver->playback.rate_min = tx_fs_rate; in qmc_audio_dai_parse()
910 qmc_soc_dai_driver->playback.rate_max = tx_fs_rate; in qmc_audio_dai_parse()
911 qmc_soc_dai_driver->capture.rates = snd_pcm_rate_to_rate_bit(rx_fs_rate); in qmc_audio_dai_parse()
912 qmc_soc_dai_driver->capture.rate_min = rx_fs_rate; in qmc_audio_dai_parse()
913 qmc_soc_dai_driver->capture.rate_max = rx_fs_rate; in qmc_audio_dai_parse()
915 qmc_soc_dai_driver->ops = &qmc_dai_ops; in qmc_audio_dai_parse()
922 struct device_node *np = pdev->dev.of_node; in qmc_audio_probe()
928 qmc_audio = devm_kzalloc(&pdev->dev, sizeof(*qmc_audio), GFP_KERNEL); in qmc_audio_probe()
930 return -ENOMEM; in qmc_audio_probe()
932 qmc_audio->dev = &pdev->dev; in qmc_audio_probe()
934 qmc_audio->num_dais = of_get_available_child_count(np); in qmc_audio_probe()
935 if (qmc_audio->num_dais) { in qmc_audio_probe()
936 qmc_audio->dais = devm_kcalloc(&pdev->dev, qmc_audio->num_dais, in qmc_audio_probe()
937 sizeof(*qmc_audio->dais), in qmc_audio_probe()
939 if (!qmc_audio->dais) in qmc_audio_probe()
940 return -ENOMEM; in qmc_audio_probe()
942 qmc_audio->dai_drivers = devm_kcalloc(&pdev->dev, qmc_audio->num_dais, in qmc_audio_probe()
943 sizeof(*qmc_audio->dai_drivers), in qmc_audio_probe()
945 if (!qmc_audio->dai_drivers) in qmc_audio_probe()
946 return -ENOMEM; in qmc_audio_probe()
952 qmc_audio->dais + i, in qmc_audio_probe()
953 qmc_audio->dai_drivers + i); in qmc_audio_probe()
963 ret = devm_snd_soc_register_component(qmc_audio->dev, in qmc_audio_probe()
965 qmc_audio->dai_drivers, in qmc_audio_probe()
966 qmc_audio->num_dais); in qmc_audio_probe()
974 { .compatible = "fsl,qmc-audio" },
981 .name = "fsl-qmc-audio",
989 MODULE_DESCRIPTION("CPM/QE QMC audio driver");