diff options
author | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2018-11-15 13:13:24 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-12-14 07:43:59 -0500 |
commit | 22930c79ac5c243c95e46508f0989e153836adc7 (patch) | |
tree | 548c1311d371c1b31a7fbfe46b3bdd85a181713c /sound | |
parent | f2e6c6aa0cb5f39e48627850680b87ec688070f8 (diff) |
ASoC: qdsp6: q6asm-dai: Add support to compress offload
This patch adds MP3 playback support in q6asm dais, adding other codec
support should be pretty trivial.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Acked-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/qcom/Kconfig | 1 | ||||
-rw-r--r-- | sound/soc/qcom/qdsp6/q6asm-dai.c | 372 |
2 files changed, 372 insertions, 1 deletions
diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 1b9fc0665792..804ae0d93058 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig | |||
@@ -66,6 +66,7 @@ config SND_SOC_QDSP6_ASM | |||
66 | tristate | 66 | tristate |
67 | 67 | ||
68 | config SND_SOC_QDSP6_ASM_DAI | 68 | config SND_SOC_QDSP6_ASM_DAI |
69 | select SND_SOC_COMPRESS | ||
69 | tristate | 70 | tristate |
70 | 71 | ||
71 | config SND_SOC_QDSP6 | 72 | config SND_SOC_QDSP6 |
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 86115de5c1b2..5b986b74dd36 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <sound/soc.h> | 10 | #include <sound/soc.h> |
11 | #include <sound/soc-dapm.h> | 11 | #include <sound/soc-dapm.h> |
12 | #include <sound/pcm.h> | 12 | #include <sound/pcm.h> |
13 | #include <linux/spinlock.h> | ||
14 | #include <sound/compress_driver.h> | ||
13 | #include <asm/dma.h> | 15 | #include <asm/dma.h> |
14 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
15 | #include <linux/of_device.h> | 17 | #include <linux/of_device.h> |
@@ -30,6 +32,15 @@ | |||
30 | #define CAPTURE_MIN_PERIOD_SIZE 320 | 32 | #define CAPTURE_MIN_PERIOD_SIZE 320 |
31 | #define SID_MASK_DEFAULT 0xF | 33 | #define SID_MASK_DEFAULT 0xF |
32 | 34 | ||
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) | ||
40 | #define Q6ASM_DAI_TX_RX 0 | ||
41 | #define Q6ASM_DAI_TX 1 | ||
42 | #define Q6ASM_DAI_RX 2 | ||
43 | |||
33 | enum stream_state { | 44 | enum stream_state { |
34 | Q6ASM_STREAM_IDLE = 0, | 45 | Q6ASM_STREAM_IDLE = 0, |
35 | Q6ASM_STREAM_STOPPED, | 46 | Q6ASM_STREAM_STOPPED, |
@@ -38,11 +49,18 @@ enum stream_state { | |||
38 | 49 | ||
39 | struct q6asm_dai_rtd { | 50 | struct q6asm_dai_rtd { |
40 | struct snd_pcm_substream *substream; | 51 | struct snd_pcm_substream *substream; |
52 | struct snd_compr_stream *cstream; | ||
53 | struct snd_compr_params codec_param; | ||
54 | struct snd_dma_buffer dma_buffer; | ||
55 | spinlock_t lock; | ||
41 | phys_addr_t phys; | 56 | phys_addr_t phys; |
42 | unsigned int pcm_size; | 57 | unsigned int pcm_size; |
43 | unsigned int pcm_count; | 58 | unsigned int pcm_count; |
44 | unsigned int pcm_irq_pos; /* IRQ position */ | 59 | unsigned int pcm_irq_pos; /* IRQ position */ |
45 | unsigned int periods; | 60 | unsigned int periods; |
61 | unsigned int bytes_sent; | ||
62 | unsigned int bytes_received; | ||
63 | unsigned int copied_total; | ||
46 | uint16_t bits_per_sample; | 64 | uint16_t bits_per_sample; |
47 | uint16_t source; /* Encoding source bit mask */ | 65 | uint16_t source; /* Encoding source bit mask */ |
48 | struct audio_client *audio_client; | 66 | struct audio_client *audio_client; |
@@ -137,6 +155,21 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = { | |||
137 | .mask = 0, | 155 | .mask = 0, |
138 | }; | 156 | }; |
139 | 157 | ||
158 | static const struct snd_compr_codec_caps q6asm_compr_caps = { | ||
159 | .num_descriptors = 1, | ||
160 | .descriptor[0].max_ch = 2, | ||
161 | .descriptor[0].sample_rates = { 8000, 11025, 12000, 16000, 22050, | ||
162 | 24000, 32000, 44100, 48000, 88200, | ||
163 | 96000, 176400, 192000 }, | ||
164 | .descriptor[0].num_sample_rates = 13, | ||
165 | .descriptor[0].bit_rate[0] = 320, | ||
166 | .descriptor[0].bit_rate[1] = 128, | ||
167 | .descriptor[0].num_bitrates = 2, | ||
168 | .descriptor[0].profiles = 0, | ||
169 | .descriptor[0].modes = SND_AUDIOCHANMODE_MP3_STEREO, | ||
170 | .descriptor[0].formats = 0, | ||
171 | }; | ||
172 | |||
140 | static void event_handler(uint32_t opcode, uint32_t token, | 173 | static void event_handler(uint32_t opcode, uint32_t token, |
141 | uint32_t *payload, void *priv) | 174 | uint32_t *payload, void *priv) |
142 | { | 175 | { |
@@ -460,6 +493,306 @@ static struct snd_pcm_ops q6asm_dai_ops = { | |||
460 | .mmap = q6asm_dai_mmap, | 493 | .mmap = q6asm_dai_mmap, |
461 | }; | 494 | }; |
462 | 495 | ||
496 | static void compress_event_handler(uint32_t opcode, uint32_t token, | ||
497 | uint32_t *payload, void *priv) | ||
498 | { | ||
499 | struct q6asm_dai_rtd *prtd = priv; | ||
500 | struct snd_compr_stream *substream = prtd->cstream; | ||
501 | unsigned long flags; | ||
502 | uint64_t avail; | ||
503 | |||
504 | switch (opcode) { | ||
505 | case ASM_CLIENT_EVENT_CMD_RUN_DONE: | ||
506 | spin_lock_irqsave(&prtd->lock, flags); | ||
507 | if (!prtd->bytes_sent) { | ||
508 | q6asm_write_async(prtd->audio_client, prtd->pcm_count, | ||
509 | 0, 0, NO_TIMESTAMP); | ||
510 | prtd->bytes_sent += prtd->pcm_count; | ||
511 | } | ||
512 | |||
513 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
514 | break; | ||
515 | |||
516 | case ASM_CLIENT_EVENT_CMD_EOS_DONE: | ||
517 | prtd->state = Q6ASM_STREAM_STOPPED; | ||
518 | break; | ||
519 | |||
520 | case ASM_CLIENT_EVENT_DATA_WRITE_DONE: | ||
521 | spin_lock_irqsave(&prtd->lock, flags); | ||
522 | |||
523 | prtd->copied_total += prtd->pcm_count; | ||
524 | snd_compr_fragment_elapsed(substream); | ||
525 | |||
526 | if (prtd->state != Q6ASM_STREAM_RUNNING) { | ||
527 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
528 | break; | ||
529 | } | ||
530 | |||
531 | avail = prtd->bytes_received - prtd->bytes_sent; | ||
532 | |||
533 | if (avail >= prtd->pcm_count) { | ||
534 | q6asm_write_async(prtd->audio_client, | ||
535 | prtd->pcm_count, 0, 0, NO_TIMESTAMP); | ||
536 | prtd->bytes_sent += prtd->pcm_count; | ||
537 | } | ||
538 | |||
539 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
540 | break; | ||
541 | |||
542 | default: | ||
543 | break; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | static int q6asm_dai_compr_open(struct snd_compr_stream *stream) | ||
548 | { | ||
549 | struct snd_soc_pcm_runtime *rtd = stream->private_data; | ||
550 | struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); | ||
551 | struct snd_compr_runtime *runtime = stream->runtime; | ||
552 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
553 | struct q6asm_dai_data *pdata; | ||
554 | struct device *dev = c->dev; | ||
555 | struct q6asm_dai_rtd *prtd; | ||
556 | int stream_id, size, ret; | ||
557 | |||
558 | stream_id = cpu_dai->driver->id; | ||
559 | pdata = snd_soc_component_get_drvdata(c); | ||
560 | if (!pdata) { | ||
561 | dev_err(dev, "Drv data not found ..\n"); | ||
562 | return -EINVAL; | ||
563 | } | ||
564 | |||
565 | prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); | ||
566 | if (!prtd) | ||
567 | return -ENOMEM; | ||
568 | |||
569 | prtd->cstream = stream; | ||
570 | prtd->audio_client = q6asm_audio_client_alloc(dev, | ||
571 | (q6asm_cb)compress_event_handler, | ||
572 | prtd, stream_id, LEGACY_PCM_MODE); | ||
573 | if (!prtd->audio_client) { | ||
574 | dev_err(dev, "Could not allocate memory\n"); | ||
575 | kfree(prtd); | ||
576 | return -ENOMEM; | ||
577 | } | ||
578 | |||
579 | size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE * | ||
580 | COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; | ||
581 | ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, dev, size, | ||
582 | &prtd->dma_buffer); | ||
583 | if (ret) { | ||
584 | dev_err(dev, "Cannot allocate buffer(s)\n"); | ||
585 | return ret; | ||
586 | } | ||
587 | |||
588 | if (pdata->sid < 0) | ||
589 | prtd->phys = prtd->dma_buffer.addr; | ||
590 | else | ||
591 | prtd->phys = prtd->dma_buffer.addr | (pdata->sid << 32); | ||
592 | |||
593 | snd_compr_set_runtime_buffer(stream, &prtd->dma_buffer); | ||
594 | spin_lock_init(&prtd->lock); | ||
595 | runtime->private_data = prtd; | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static int q6asm_dai_compr_free(struct snd_compr_stream *stream) | ||
601 | { | ||
602 | struct snd_compr_runtime *runtime = stream->runtime; | ||
603 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
604 | struct snd_soc_pcm_runtime *rtd = stream->private_data; | ||
605 | |||
606 | if (prtd->audio_client) { | ||
607 | if (prtd->state) | ||
608 | q6asm_cmd(prtd->audio_client, CMD_CLOSE); | ||
609 | |||
610 | snd_dma_free_pages(&prtd->dma_buffer); | ||
611 | q6asm_unmap_memory_regions(stream->direction, | ||
612 | prtd->audio_client); | ||
613 | q6asm_audio_client_free(prtd->audio_client); | ||
614 | prtd->audio_client = NULL; | ||
615 | } | ||
616 | q6routing_stream_close(rtd->dai_link->id, stream->direction); | ||
617 | kfree(prtd); | ||
618 | |||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | static int q6asm_dai_compr_set_params(struct snd_compr_stream *stream, | ||
623 | struct snd_compr_params *params) | ||
624 | { | ||
625 | struct snd_compr_runtime *runtime = stream->runtime; | ||
626 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
627 | struct snd_soc_pcm_runtime *rtd = stream->private_data; | ||
628 | struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); | ||
629 | int dir = stream->direction; | ||
630 | struct q6asm_dai_data *pdata; | ||
631 | struct device *dev = c->dev; | ||
632 | int ret; | ||
633 | |||
634 | memcpy(&prtd->codec_param, params, sizeof(*params)); | ||
635 | |||
636 | pdata = snd_soc_component_get_drvdata(c); | ||
637 | if (!pdata) | ||
638 | return -EINVAL; | ||
639 | |||
640 | if (!prtd || !prtd->audio_client) { | ||
641 | dev_err(dev, "private data null or audio client freed\n"); | ||
642 | return -EINVAL; | ||
643 | } | ||
644 | |||
645 | prtd->periods = runtime->fragments; | ||
646 | prtd->pcm_count = runtime->fragment_size; | ||
647 | prtd->pcm_size = runtime->fragments * runtime->fragment_size; | ||
648 | prtd->bits_per_sample = 16; | ||
649 | if (dir == SND_COMPRESS_PLAYBACK) { | ||
650 | ret = q6asm_open_write(prtd->audio_client, params->codec.id, | ||
651 | prtd->bits_per_sample); | ||
652 | |||
653 | if (ret < 0) { | ||
654 | dev_err(dev, "q6asm_open_write failed\n"); | ||
655 | q6asm_audio_client_free(prtd->audio_client); | ||
656 | prtd->audio_client = NULL; | ||
657 | return ret; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | prtd->session_id = q6asm_get_session_id(prtd->audio_client); | ||
662 | ret = q6routing_stream_open(rtd->dai_link->id, LEGACY_PCM_MODE, | ||
663 | prtd->session_id, dir); | ||
664 | if (ret) { | ||
665 | dev_err(dev, "Stream reg failed ret:%d\n", ret); | ||
666 | return ret; | ||
667 | } | ||
668 | |||
669 | ret = q6asm_map_memory_regions(dir, prtd->audio_client, prtd->phys, | ||
670 | (prtd->pcm_size / prtd->periods), | ||
671 | prtd->periods); | ||
672 | |||
673 | if (ret < 0) { | ||
674 | dev_err(dev, "Buffer Mapping failed ret:%d\n", ret); | ||
675 | return -ENOMEM; | ||
676 | } | ||
677 | |||
678 | prtd->state = Q6ASM_STREAM_RUNNING; | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static int q6asm_dai_compr_trigger(struct snd_compr_stream *stream, int cmd) | ||
684 | { | ||
685 | struct snd_compr_runtime *runtime = stream->runtime; | ||
686 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
687 | int ret = 0; | ||
688 | |||
689 | switch (cmd) { | ||
690 | case SNDRV_PCM_TRIGGER_START: | ||
691 | case SNDRV_PCM_TRIGGER_RESUME: | ||
692 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
693 | ret = q6asm_run_nowait(prtd->audio_client, 0, 0, 0); | ||
694 | break; | ||
695 | case SNDRV_PCM_TRIGGER_STOP: | ||
696 | prtd->state = Q6ASM_STREAM_STOPPED; | ||
697 | ret = q6asm_cmd_nowait(prtd->audio_client, CMD_EOS); | ||
698 | break; | ||
699 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
700 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
701 | ret = q6asm_cmd_nowait(prtd->audio_client, CMD_PAUSE); | ||
702 | break; | ||
703 | default: | ||
704 | ret = -EINVAL; | ||
705 | break; | ||
706 | } | ||
707 | |||
708 | return ret; | ||
709 | } | ||
710 | |||
711 | static int q6asm_dai_compr_pointer(struct snd_compr_stream *stream, | ||
712 | struct snd_compr_tstamp *tstamp) | ||
713 | { | ||
714 | struct snd_compr_runtime *runtime = stream->runtime; | ||
715 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
716 | unsigned long flags; | ||
717 | |||
718 | spin_lock_irqsave(&prtd->lock, flags); | ||
719 | |||
720 | tstamp->copied_total = prtd->copied_total; | ||
721 | tstamp->byte_offset = prtd->copied_total % prtd->pcm_size; | ||
722 | |||
723 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static int q6asm_dai_compr_ack(struct snd_compr_stream *stream, | ||
729 | size_t count) | ||
730 | { | ||
731 | struct snd_compr_runtime *runtime = stream->runtime; | ||
732 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
733 | unsigned long flags; | ||
734 | |||
735 | spin_lock_irqsave(&prtd->lock, flags); | ||
736 | prtd->bytes_received += count; | ||
737 | spin_unlock_irqrestore(&prtd->lock, flags); | ||
738 | |||
739 | return count; | ||
740 | } | ||
741 | |||
742 | static int q6asm_dai_compr_mmap(struct snd_compr_stream *stream, | ||
743 | struct vm_area_struct *vma) | ||
744 | { | ||
745 | struct snd_compr_runtime *runtime = stream->runtime; | ||
746 | struct q6asm_dai_rtd *prtd = runtime->private_data; | ||
747 | struct snd_soc_pcm_runtime *rtd = stream->private_data; | ||
748 | struct snd_soc_component *c = snd_soc_rtdcom_lookup(rtd, DRV_NAME); | ||
749 | struct device *dev = c->dev; | ||
750 | |||
751 | return dma_mmap_coherent(dev, vma, | ||
752 | prtd->dma_buffer.area, prtd->dma_buffer.addr, | ||
753 | prtd->dma_buffer.bytes); | ||
754 | } | ||
755 | |||
756 | static int q6asm_dai_compr_get_caps(struct snd_compr_stream *stream, | ||
757 | struct snd_compr_caps *caps) | ||
758 | { | ||
759 | caps->direction = SND_COMPRESS_PLAYBACK; | ||
760 | caps->min_fragment_size = COMPR_PLAYBACK_MIN_FRAGMENT_SIZE; | ||
761 | caps->max_fragment_size = COMPR_PLAYBACK_MAX_FRAGMENT_SIZE; | ||
762 | caps->min_fragments = COMPR_PLAYBACK_MIN_NUM_FRAGMENTS; | ||
763 | caps->max_fragments = COMPR_PLAYBACK_MAX_NUM_FRAGMENTS; | ||
764 | caps->num_codecs = 1; | ||
765 | caps->codecs[0] = SND_AUDIOCODEC_MP3; | ||
766 | |||
767 | return 0; | ||
768 | } | ||
769 | |||
770 | static int q6asm_dai_compr_get_codec_caps(struct snd_compr_stream *stream, | ||
771 | struct snd_compr_codec_caps *codec) | ||
772 | { | ||
773 | switch (codec->codec) { | ||
774 | case SND_AUDIOCODEC_MP3: | ||
775 | *codec = q6asm_compr_caps; | ||
776 | break; | ||
777 | default: | ||
778 | break; | ||
779 | } | ||
780 | |||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static struct snd_compr_ops q6asm_dai_compr_ops = { | ||
785 | .open = q6asm_dai_compr_open, | ||
786 | .free = q6asm_dai_compr_free, | ||
787 | .set_params = q6asm_dai_compr_set_params, | ||
788 | .pointer = q6asm_dai_compr_pointer, | ||
789 | .trigger = q6asm_dai_compr_trigger, | ||
790 | .get_caps = q6asm_dai_compr_get_caps, | ||
791 | .get_codec_caps = q6asm_dai_compr_get_codec_caps, | ||
792 | .mmap = q6asm_dai_compr_mmap, | ||
793 | .ack = q6asm_dai_compr_ack, | ||
794 | }; | ||
795 | |||
463 | static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) | 796 | static int q6asm_dai_pcm_new(struct snd_soc_pcm_runtime *rtd) |
464 | { | 797 | { |
465 | struct snd_pcm_substream *psubstream, *csubstream; | 798 | struct snd_pcm_substream *psubstream, *csubstream; |
@@ -515,7 +848,7 @@ static const struct snd_soc_component_driver q6asm_fe_dai_component = { | |||
515 | .ops = &q6asm_dai_ops, | 848 | .ops = &q6asm_dai_ops, |
516 | .pcm_new = q6asm_dai_pcm_new, | 849 | .pcm_new = q6asm_dai_pcm_new, |
517 | .pcm_free = q6asm_dai_pcm_free, | 850 | .pcm_free = q6asm_dai_pcm_free, |
518 | 851 | .compr_ops = &q6asm_dai_compr_ops, | |
519 | }; | 852 | }; |
520 | 853 | ||
521 | static struct snd_soc_dai_driver q6asm_fe_dais[] = { | 854 | static struct snd_soc_dai_driver q6asm_fe_dais[] = { |
@@ -529,6 +862,41 @@ static struct snd_soc_dai_driver q6asm_fe_dais[] = { | |||
529 | Q6ASM_FEDAI_DRIVER(8), | 862 | Q6ASM_FEDAI_DRIVER(8), |
530 | }; | 863 | }; |
531 | 864 | ||
865 | static int of_q6asm_parse_dai_data(struct device *dev, | ||
866 | struct q6asm_dai_data *pdata) | ||
867 | { | ||
868 | static struct snd_soc_dai_driver *dai_drv; | ||
869 | struct snd_soc_pcm_stream empty_stream; | ||
870 | struct device_node *node; | ||
871 | int ret, id, dir; | ||
872 | |||
873 | memset(&empty_stream, 0, sizeof(empty_stream)); | ||
874 | |||
875 | for_each_child_of_node(dev->of_node, node) { | ||
876 | ret = of_property_read_u32(node, "reg", &id); | ||
877 | if (ret || id > MAX_SESSIONS || id < 0) { | ||
878 | dev_err(dev, "valid dai id not found:%d\n", ret); | ||
879 | continue; | ||
880 | } | ||
881 | |||
882 | dai_drv = &q6asm_fe_dais[id]; | ||
883 | |||
884 | ret = of_property_read_u32(node, "direction", &dir); | ||
885 | if (ret) | ||
886 | continue; | ||
887 | |||
888 | if (dir == Q6ASM_DAI_RX) | ||
889 | dai_drv->capture = empty_stream; | ||
890 | else if (dir == Q6ASM_DAI_TX) | ||
891 | dai_drv->playback = empty_stream; | ||
892 | |||
893 | if (of_property_read_bool(node, "is-compress-dai")) | ||
894 | dai_drv->compress_new = snd_soc_new_compress; | ||
895 | } | ||
896 | |||
897 | return 0; | ||
898 | } | ||
899 | |||
532 | static int q6asm_dai_probe(struct platform_device *pdev) | 900 | static int q6asm_dai_probe(struct platform_device *pdev) |
533 | { | 901 | { |
534 | struct device *dev = &pdev->dev; | 902 | struct device *dev = &pdev->dev; |
@@ -549,6 +917,8 @@ static int q6asm_dai_probe(struct platform_device *pdev) | |||
549 | 917 | ||
550 | dev_set_drvdata(dev, pdata); | 918 | dev_set_drvdata(dev, pdata); |
551 | 919 | ||
920 | of_q6asm_parse_dai_data(dev, pdata); | ||
921 | |||
552 | return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, | 922 | return devm_snd_soc_register_component(dev, &q6asm_fe_dai_component, |
553 | q6asm_fe_dais, | 923 | q6asm_fe_dais, |
554 | ARRAY_SIZE(q6asm_fe_dais)); | 924 | ARRAY_SIZE(q6asm_fe_dais)); |