diff options
author | Subhransu S. Prusty <subhransu.s.prusty@intel.com> | 2016-02-11 21:16:04 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-02-15 15:54:03 -0500 |
commit | 17a42c4500b05a6af4c32eb8e9cfc44bab945d1f (patch) | |
tree | c201c409f3a48f0d2baa364fd910fc386a155d63 | |
parent | 211caab73b20dcc91ac103db0f68fe2388120d59 (diff) |
ASoC: hdac_hdmi: create dais based on number of cvts
After enabling all pins/cvts, Skylake HDMI codec enumerates 3
converters. Three independent streams can be supported with 3
cvts. This patch removes the static dai creation and creates dais
based on the number of cvts queried.
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/codecs/hdac_hdmi.c | 123 |
1 files changed, 91 insertions, 32 deletions
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index b2e5e549b022..c85deae68064 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include <sound/pcm_drm_eld.h> | 30 | #include <sound/pcm_drm_eld.h> |
31 | #include "../../hda/local.h" | 31 | #include "../../hda/local.h" |
32 | 32 | ||
33 | #define NAME_SIZE 32 | ||
34 | |||
33 | #define AMP_OUT_MUTE 0xb080 | 35 | #define AMP_OUT_MUTE 0xb080 |
34 | #define AMP_OUT_UNMUTE 0xb000 | 36 | #define AMP_OUT_UNMUTE 0xb000 |
35 | #define PIN_OUT (AC_PINCTL_OUT_EN) | 37 | #define PIN_OUT (AC_PINCTL_OUT_EN) |
@@ -669,11 +671,82 @@ static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac) | |||
669 | 671 | ||
670 | } | 672 | } |
671 | 673 | ||
674 | static struct snd_soc_dai_ops hdmi_dai_ops = { | ||
675 | .startup = hdac_hdmi_pcm_open, | ||
676 | .shutdown = hdac_hdmi_pcm_close, | ||
677 | .hw_params = hdac_hdmi_set_hw_params, | ||
678 | .prepare = hdac_hdmi_playback_prepare, | ||
679 | .hw_free = hdac_hdmi_playback_cleanup, | ||
680 | }; | ||
681 | |||
682 | /* | ||
683 | * Each converter can support a stream independently. So a dai is created | ||
684 | * based on the number of converter queried. | ||
685 | */ | ||
686 | static int hdac_hdmi_create_dais(struct hdac_device *hdac, | ||
687 | struct snd_soc_dai_driver **dais, | ||
688 | struct hdac_hdmi_priv *hdmi, int num_dais) | ||
689 | { | ||
690 | struct snd_soc_dai_driver *hdmi_dais; | ||
691 | struct hdac_hdmi_cvt *cvt; | ||
692 | char name[NAME_SIZE], dai_name[NAME_SIZE]; | ||
693 | int i = 0; | ||
694 | u32 rates, bps; | ||
695 | unsigned int rate_max = 384000, rate_min = 8000; | ||
696 | u64 formats; | ||
697 | int ret; | ||
698 | |||
699 | hdmi_dais = devm_kzalloc(&hdac->dev, | ||
700 | (sizeof(*hdmi_dais) * num_dais), | ||
701 | GFP_KERNEL); | ||
702 | if (!hdmi_dais) | ||
703 | return -ENOMEM; | ||
704 | |||
705 | list_for_each_entry(cvt, &hdmi->cvt_list, head) { | ||
706 | ret = snd_hdac_query_supported_pcm(hdac, cvt->nid, | ||
707 | &rates, &formats, &bps); | ||
708 | if (ret) | ||
709 | return ret; | ||
710 | |||
711 | sprintf(dai_name, "intel-hdmi-hifi%d", i+1); | ||
712 | hdmi_dais[i].name = devm_kstrdup(&hdac->dev, | ||
713 | dai_name, GFP_KERNEL); | ||
714 | |||
715 | if (!hdmi_dais[i].name) | ||
716 | return -ENOMEM; | ||
717 | |||
718 | snprintf(name, sizeof(name), "hifi%d", i+1); | ||
719 | hdmi_dais[i].playback.stream_name = | ||
720 | devm_kstrdup(&hdac->dev, name, GFP_KERNEL); | ||
721 | if (!hdmi_dais[i].playback.stream_name) | ||
722 | return -ENOMEM; | ||
723 | |||
724 | /* | ||
725 | * Set caps based on capability queried from the converter. | ||
726 | * It will be constrained runtime based on ELD queried. | ||
727 | */ | ||
728 | hdmi_dais[i].playback.formats = formats; | ||
729 | hdmi_dais[i].playback.rates = rates; | ||
730 | hdmi_dais[i].playback.rate_max = rate_max; | ||
731 | hdmi_dais[i].playback.rate_min = rate_min; | ||
732 | hdmi_dais[i].playback.channels_min = 2; | ||
733 | hdmi_dais[i].playback.channels_max = 2; | ||
734 | hdmi_dais[i].ops = &hdmi_dai_ops; | ||
735 | |||
736 | i++; | ||
737 | } | ||
738 | |||
739 | *dais = hdmi_dais; | ||
740 | |||
741 | return 0; | ||
742 | } | ||
743 | |||
672 | /* | 744 | /* |
673 | * Parse all nodes and store the cvt/pin nids in array | 745 | * Parse all nodes and store the cvt/pin nids in array |
674 | * Add one time initialization for pin and cvt widgets | 746 | * Add one time initialization for pin and cvt widgets |
675 | */ | 747 | */ |
676 | static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev) | 748 | static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev, |
749 | struct snd_soc_dai_driver **dais, int *num_dais) | ||
677 | { | 750 | { |
678 | hda_nid_t nid; | 751 | hda_nid_t nid; |
679 | int i, num_nodes; | 752 | int i, num_nodes; |
@@ -724,6 +797,15 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev) | |||
724 | if (!hdmi->num_pin || !hdmi->num_cvt) | 797 | if (!hdmi->num_pin || !hdmi->num_cvt) |
725 | return -EIO; | 798 | return -EIO; |
726 | 799 | ||
800 | ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt); | ||
801 | if (ret) { | ||
802 | dev_err(&hdac->dev, "Failed to create dais with err: %d\n", | ||
803 | ret); | ||
804 | return ret; | ||
805 | } | ||
806 | |||
807 | *num_dais = hdmi->num_cvt; | ||
808 | |||
727 | return hdac_hdmi_init_dai_map(edev); | 809 | return hdac_hdmi_init_dai_map(edev); |
728 | } | 810 | } |
729 | 811 | ||
@@ -814,38 +896,12 @@ static struct snd_soc_codec_driver hdmi_hda_codec = { | |||
814 | .idle_bias_off = true, | 896 | .idle_bias_off = true, |
815 | }; | 897 | }; |
816 | 898 | ||
817 | static struct snd_soc_dai_ops hdmi_dai_ops = { | ||
818 | .startup = hdac_hdmi_pcm_open, | ||
819 | .shutdown = hdac_hdmi_pcm_close, | ||
820 | .hw_params = hdac_hdmi_set_hw_params, | ||
821 | .prepare = hdac_hdmi_playback_prepare, | ||
822 | .hw_free = hdac_hdmi_playback_cleanup, | ||
823 | }; | ||
824 | |||
825 | static struct snd_soc_dai_driver hdmi_dais[] = { | ||
826 | { .name = "intel-hdmi-hif1", | ||
827 | .playback = { | ||
828 | .stream_name = "hif1", | ||
829 | .channels_min = 2, | ||
830 | .channels_max = 2, | ||
831 | .rates = SNDRV_PCM_RATE_32000 | | ||
832 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | | ||
833 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | | ||
834 | SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000, | ||
835 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
836 | SNDRV_PCM_FMTBIT_S20_3LE | | ||
837 | SNDRV_PCM_FMTBIT_S24_LE | | ||
838 | SNDRV_PCM_FMTBIT_S32_LE, | ||
839 | |||
840 | }, | ||
841 | .ops = &hdmi_dai_ops, | ||
842 | }, | ||
843 | }; | ||
844 | |||
845 | static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | 899 | static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) |
846 | { | 900 | { |
847 | struct hdac_device *codec = &edev->hdac; | 901 | struct hdac_device *codec = &edev->hdac; |
848 | struct hdac_hdmi_priv *hdmi_priv; | 902 | struct hdac_hdmi_priv *hdmi_priv; |
903 | struct snd_soc_dai_driver *hdmi_dais = NULL; | ||
904 | int num_dais = 0; | ||
849 | int ret = 0; | 905 | int ret = 0; |
850 | 906 | ||
851 | hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL); | 907 | hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL); |
@@ -859,13 +915,16 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | |||
859 | INIT_LIST_HEAD(&hdmi_priv->pin_list); | 915 | INIT_LIST_HEAD(&hdmi_priv->pin_list); |
860 | INIT_LIST_HEAD(&hdmi_priv->cvt_list); | 916 | INIT_LIST_HEAD(&hdmi_priv->cvt_list); |
861 | 917 | ||
862 | ret = hdac_hdmi_parse_and_map_nid(edev); | 918 | ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais); |
863 | if (ret < 0) | 919 | if (ret < 0) { |
920 | dev_err(&codec->dev, | ||
921 | "Failed in parse and map nid with err: %d\n", ret); | ||
864 | return ret; | 922 | return ret; |
923 | } | ||
865 | 924 | ||
866 | /* ASoC specific initialization */ | 925 | /* ASoC specific initialization */ |
867 | return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec, | 926 | return snd_soc_register_codec(&codec->dev, &hdmi_hda_codec, |
868 | hdmi_dais, ARRAY_SIZE(hdmi_dais)); | 927 | hdmi_dais, num_dais); |
869 | } | 928 | } |
870 | 929 | ||
871 | static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) | 930 | static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) |