diff options
Diffstat (limited to 'sound/soc/ux500/ux500_msp_dai.c')
-rw-r--r-- | sound/soc/ux500/ux500_msp_dai.c | 146 |
1 files changed, 60 insertions, 86 deletions
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index c6fb5cce980e..5f4807b2c007 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -17,12 +17,14 @@ | |||
17 | #include <linux/bitops.h> | 17 | #include <linux/bitops.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
20 | #include <linux/of.h> | ||
20 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
21 | #include <linux/mfd/dbx500-prcmu.h> | 22 | #include <linux/mfd/dbx500-prcmu.h> |
22 | #include <linux/platform_data/asoc-ux500-msp.h> | 23 | #include <linux/platform_data/asoc-ux500-msp.h> |
23 | 24 | ||
24 | #include <sound/soc.h> | 25 | #include <sound/soc.h> |
25 | #include <sound/soc-dai.h> | 26 | #include <sound/soc-dai.h> |
27 | #include <sound/dmaengine_pcm.h> | ||
26 | 28 | ||
27 | #include "ux500_msp_i2s.h" | 29 | #include "ux500_msp_i2s.h" |
28 | #include "ux500_msp_dai.h" | 30 | #include "ux500_msp_dai.h" |
@@ -654,16 +656,52 @@ static int ux500_msp_dai_trigger(struct snd_pcm_substream *substream, | |||
654 | return ret; | 656 | return ret; |
655 | } | 657 | } |
656 | 658 | ||
659 | static int ux500_msp_dai_of_probe(struct snd_soc_dai *dai) | ||
660 | { | ||
661 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); | ||
662 | struct snd_dmaengine_dai_dma_data *playback_dma_data; | ||
663 | struct snd_dmaengine_dai_dma_data *capture_dma_data; | ||
664 | |||
665 | playback_dma_data = devm_kzalloc(dai->dev, | ||
666 | sizeof(*playback_dma_data), | ||
667 | GFP_KERNEL); | ||
668 | if (!playback_dma_data) | ||
669 | return -ENOMEM; | ||
670 | |||
671 | capture_dma_data = devm_kzalloc(dai->dev, | ||
672 | sizeof(*capture_dma_data), | ||
673 | GFP_KERNEL); | ||
674 | if (!capture_dma_data) | ||
675 | return -ENOMEM; | ||
676 | |||
677 | playback_dma_data->addr = drvdata->msp->playback_dma_data.tx_rx_addr; | ||
678 | capture_dma_data->addr = drvdata->msp->capture_dma_data.tx_rx_addr; | ||
679 | |||
680 | playback_dma_data->maxburst = 4; | ||
681 | capture_dma_data->maxburst = 4; | ||
682 | |||
683 | snd_soc_dai_init_dma_data(dai, playback_dma_data, capture_dma_data); | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | |||
657 | static int ux500_msp_dai_probe(struct snd_soc_dai *dai) | 688 | static int ux500_msp_dai_probe(struct snd_soc_dai *dai) |
658 | { | 689 | { |
659 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); | 690 | struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev); |
691 | struct msp_i2s_platform_data *pdata = dai->dev->platform_data; | ||
692 | int ret; | ||
660 | 693 | ||
661 | dai->playback_dma_data = &drvdata->msp->playback_dma_data; | 694 | if (!pdata) { |
662 | dai->capture_dma_data = &drvdata->msp->capture_dma_data; | 695 | ret = ux500_msp_dai_of_probe(dai); |
696 | return ret; | ||
697 | } | ||
663 | 698 | ||
664 | drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; | 699 | drvdata->msp->playback_dma_data.data_size = drvdata->slot_width; |
665 | drvdata->msp->capture_dma_data.data_size = drvdata->slot_width; | 700 | drvdata->msp->capture_dma_data.data_size = drvdata->slot_width; |
666 | 701 | ||
702 | snd_soc_dai_init_dma_data(dai, | ||
703 | &drvdata->msp->playback_dma_data, | ||
704 | &drvdata->msp->capture_dma_data); | ||
667 | return 0; | 705 | return 0; |
668 | } | 706 | } |
669 | 707 | ||
@@ -680,87 +718,19 @@ static struct snd_soc_dai_ops ux500_msp_dai_ops[] = { | |||
680 | } | 718 | } |
681 | }; | 719 | }; |
682 | 720 | ||
683 | static struct snd_soc_dai_driver ux500_msp_dai_drv[UX500_NBR_OF_DAI] = { | 721 | static struct snd_soc_dai_driver ux500_msp_dai_drv = { |
684 | { | 722 | .probe = ux500_msp_dai_probe, |
685 | .name = "ux500-msp-i2s.0", | 723 | .suspend = NULL, |
686 | .probe = ux500_msp_dai_probe, | 724 | .resume = NULL, |
687 | .id = 0, | 725 | .playback.channels_min = UX500_MSP_MIN_CHANNELS, |
688 | .suspend = NULL, | 726 | .playback.channels_max = UX500_MSP_MAX_CHANNELS, |
689 | .resume = NULL, | 727 | .playback.rates = UX500_I2S_RATES, |
690 | .playback = { | 728 | .playback.formats = UX500_I2S_FORMATS, |
691 | .channels_min = UX500_MSP_MIN_CHANNELS, | 729 | .capture.channels_min = UX500_MSP_MIN_CHANNELS, |
692 | .channels_max = UX500_MSP_MAX_CHANNELS, | 730 | .capture.channels_max = UX500_MSP_MAX_CHANNELS, |
693 | .rates = UX500_I2S_RATES, | 731 | .capture.rates = UX500_I2S_RATES, |
694 | .formats = UX500_I2S_FORMATS, | 732 | .capture.formats = UX500_I2S_FORMATS, |
695 | }, | 733 | .ops = ux500_msp_dai_ops, |
696 | .capture = { | ||
697 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
698 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
699 | .rates = UX500_I2S_RATES, | ||
700 | .formats = UX500_I2S_FORMATS, | ||
701 | }, | ||
702 | .ops = ux500_msp_dai_ops, | ||
703 | }, | ||
704 | { | ||
705 | .name = "ux500-msp-i2s.1", | ||
706 | .probe = ux500_msp_dai_probe, | ||
707 | .id = 1, | ||
708 | .suspend = NULL, | ||
709 | .resume = NULL, | ||
710 | .playback = { | ||
711 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
712 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
713 | .rates = UX500_I2S_RATES, | ||
714 | .formats = UX500_I2S_FORMATS, | ||
715 | }, | ||
716 | .capture = { | ||
717 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
718 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
719 | .rates = UX500_I2S_RATES, | ||
720 | .formats = UX500_I2S_FORMATS, | ||
721 | }, | ||
722 | .ops = ux500_msp_dai_ops, | ||
723 | }, | ||
724 | { | ||
725 | .name = "ux500-msp-i2s.2", | ||
726 | .id = 2, | ||
727 | .probe = ux500_msp_dai_probe, | ||
728 | .suspend = NULL, | ||
729 | .resume = NULL, | ||
730 | .playback = { | ||
731 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
732 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
733 | .rates = UX500_I2S_RATES, | ||
734 | .formats = UX500_I2S_FORMATS, | ||
735 | }, | ||
736 | .capture = { | ||
737 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
738 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
739 | .rates = UX500_I2S_RATES, | ||
740 | .formats = UX500_I2S_FORMATS, | ||
741 | }, | ||
742 | .ops = ux500_msp_dai_ops, | ||
743 | }, | ||
744 | { | ||
745 | .name = "ux500-msp-i2s.3", | ||
746 | .probe = ux500_msp_dai_probe, | ||
747 | .id = 3, | ||
748 | .suspend = NULL, | ||
749 | .resume = NULL, | ||
750 | .playback = { | ||
751 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
752 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
753 | .rates = UX500_I2S_RATES, | ||
754 | .formats = UX500_I2S_FORMATS, | ||
755 | }, | ||
756 | .capture = { | ||
757 | .channels_min = UX500_MSP_MIN_CHANNELS, | ||
758 | .channels_max = UX500_MSP_MAX_CHANNELS, | ||
759 | .rates = UX500_I2S_RATES, | ||
760 | .formats = UX500_I2S_FORMATS, | ||
761 | }, | ||
762 | .ops = ux500_msp_dai_ops, | ||
763 | }, | ||
764 | }; | 734 | }; |
765 | 735 | ||
766 | static const struct snd_soc_component_driver ux500_msp_component = { | 736 | static const struct snd_soc_component_driver ux500_msp_component = { |
@@ -771,10 +741,14 @@ static const struct snd_soc_component_driver ux500_msp_component = { | |||
771 | static int ux500_msp_drv_probe(struct platform_device *pdev) | 741 | static int ux500_msp_drv_probe(struct platform_device *pdev) |
772 | { | 742 | { |
773 | struct ux500_msp_i2s_drvdata *drvdata; | 743 | struct ux500_msp_i2s_drvdata *drvdata; |
744 | struct msp_i2s_platform_data *pdata = pdev->dev.platform_data; | ||
745 | struct device_node *np = pdev->dev.of_node; | ||
774 | int ret = 0; | 746 | int ret = 0; |
775 | 747 | ||
776 | dev_dbg(&pdev->dev, "%s: Enter (pdev->name = %s).\n", __func__, | 748 | if (!pdata && !np) { |
777 | pdev->name); | 749 | dev_err(&pdev->dev, "No platform data or Device Tree found\n"); |
750 | return -ENODEV; | ||
751 | } | ||
778 | 752 | ||
779 | drvdata = devm_kzalloc(&pdev->dev, | 753 | drvdata = devm_kzalloc(&pdev->dev, |
780 | sizeof(struct ux500_msp_i2s_drvdata), | 754 | sizeof(struct ux500_msp_i2s_drvdata), |
@@ -826,7 +800,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev) | |||
826 | dev_set_drvdata(&pdev->dev, drvdata); | 800 | dev_set_drvdata(&pdev->dev, drvdata); |
827 | 801 | ||
828 | ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, | 802 | ret = snd_soc_register_component(&pdev->dev, &ux500_msp_component, |
829 | &ux500_msp_dai_drv[drvdata->msp->id], 1); | 803 | &ux500_msp_dai_drv, 1); |
830 | if (ret < 0) { | 804 | if (ret < 0) { |
831 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", | 805 | dev_err(&pdev->dev, "Error: %s: Failed to register MSP%d!\n", |
832 | __func__, drvdata->msp->id); | 806 | __func__, drvdata->msp->id); |