diff options
-rw-r--r-- | sound/soc/soc-topology.c | 113 |
1 files changed, 111 insertions, 2 deletions
diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index ee7f15aa46fc..05a18f68bfd0 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c | |||
@@ -48,9 +48,10 @@ | |||
48 | #define SOC_TPLG_PASS_PCM_DAI 4 | 48 | #define SOC_TPLG_PASS_PCM_DAI 4 |
49 | #define SOC_TPLG_PASS_GRAPH 5 | 49 | #define SOC_TPLG_PASS_GRAPH 5 |
50 | #define SOC_TPLG_PASS_PINS 6 | 50 | #define SOC_TPLG_PASS_PINS 6 |
51 | #define SOC_TPLG_PASS_BE_DAI 7 | ||
51 | 52 | ||
52 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST | 53 | #define SOC_TPLG_PASS_START SOC_TPLG_PASS_MANIFEST |
53 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_PINS | 54 | #define SOC_TPLG_PASS_END SOC_TPLG_PASS_BE_DAI |
54 | 55 | ||
55 | struct soc_tplg { | 56 | struct soc_tplg { |
56 | const struct firmware *fw; | 57 | const struct firmware *fw; |
@@ -1556,6 +1557,24 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream, | |||
1556 | stream->formats = caps->formats; | 1557 | stream->formats = caps->formats; |
1557 | } | 1558 | } |
1558 | 1559 | ||
1560 | static void set_dai_flags(struct snd_soc_dai_driver *dai_drv, | ||
1561 | unsigned int flag_mask, unsigned int flags) | ||
1562 | { | ||
1563 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES) | ||
1564 | dai_drv->symmetric_rates = | ||
1565 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_RATES ? 1 : 0; | ||
1566 | |||
1567 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS) | ||
1568 | dai_drv->symmetric_channels = | ||
1569 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS ? | ||
1570 | 1 : 0; | ||
1571 | |||
1572 | if (flag_mask & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS) | ||
1573 | dai_drv->symmetric_samplebits = | ||
1574 | flags & SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS ? | ||
1575 | 1 : 0; | ||
1576 | } | ||
1577 | |||
1559 | static int soc_tplg_dai_create(struct soc_tplg *tplg, | 1578 | static int soc_tplg_dai_create(struct soc_tplg *tplg, |
1560 | struct snd_soc_tplg_pcm *pcm) | 1579 | struct snd_soc_tplg_pcm *pcm) |
1561 | { | 1580 | { |
@@ -1690,8 +1709,96 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg, | |||
1690 | return 0; | 1709 | return 0; |
1691 | } | 1710 | } |
1692 | 1711 | ||
1712 | /* * | ||
1713 | * soc_tplg_be_dai_config - Find and configure an existing BE DAI. | ||
1714 | * @tplg: topology context | ||
1715 | * @be: topology BE DAI configs. | ||
1716 | * | ||
1717 | * The BE dai should already be registered by the platform driver. The | ||
1718 | * platform driver should specify the BE DAI name and ID for matching. | ||
1719 | */ | ||
1720 | static int soc_tplg_be_dai_config(struct soc_tplg *tplg, | ||
1721 | struct snd_soc_tplg_be_dai *be) | ||
1722 | { | ||
1723 | struct snd_soc_dai_link_component dai_component = {0}; | ||
1724 | struct snd_soc_dai *dai; | ||
1725 | struct snd_soc_dai_driver *dai_drv; | ||
1726 | struct snd_soc_pcm_stream *stream; | ||
1727 | struct snd_soc_tplg_stream_caps *caps; | ||
1728 | int ret; | ||
1729 | |||
1730 | dai_component.dai_name = be->dai_name; | ||
1731 | dai = snd_soc_find_dai(&dai_component); | ||
1732 | if (!dai) { | ||
1733 | dev_err(tplg->dev, "ASoC: BE DAI %s not registered\n", | ||
1734 | be->dai_name); | ||
1735 | return -EINVAL; | ||
1736 | } | ||
1737 | |||
1738 | if (be->dai_id != dai->id) { | ||
1739 | dev_err(tplg->dev, "ASoC: BE DAI %s id mismatch\n", | ||
1740 | be->dai_name); | ||
1741 | return -EINVAL; | ||
1742 | } | ||
1743 | |||
1744 | dai_drv = dai->driver; | ||
1745 | if (!dai_drv) | ||
1746 | return -EINVAL; | ||
1747 | |||
1748 | if (be->playback) { | ||
1749 | stream = &dai_drv->playback; | ||
1750 | caps = &be->caps[SND_SOC_TPLG_STREAM_PLAYBACK]; | ||
1751 | set_stream_info(stream, caps); | ||
1752 | } | ||
1753 | |||
1754 | if (be->capture) { | ||
1755 | stream = &dai_drv->capture; | ||
1756 | caps = &be->caps[SND_SOC_TPLG_STREAM_CAPTURE]; | ||
1757 | set_stream_info(stream, caps); | ||
1758 | } | ||
1759 | |||
1760 | if (be->flag_mask) | ||
1761 | set_dai_flags(dai_drv, be->flag_mask, be->flags); | ||
1762 | |||
1763 | /* pass control to component driver for optional further init */ | ||
1764 | ret = soc_tplg_dai_load(tplg, dai_drv); | ||
1765 | if (ret < 0) { | ||
1766 | dev_err(tplg->comp->dev, "ASoC: DAI loading failed\n"); | ||
1767 | return ret; | ||
1768 | } | ||
1769 | |||
1770 | return 0; | ||
1771 | } | ||
1772 | |||
1773 | static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg, | ||
1774 | struct snd_soc_tplg_hdr *hdr) | ||
1775 | { | ||
1776 | struct snd_soc_tplg_be_dai *be; | ||
1777 | int count = hdr->count; | ||
1778 | int i; | ||
1779 | |||
1780 | if (tplg->pass != SOC_TPLG_PASS_BE_DAI) | ||
1781 | return 0; | ||
1782 | |||
1783 | /* config the existing BE DAIs */ | ||
1784 | for (i = 0; i < count; i++) { | ||
1785 | be = (struct snd_soc_tplg_be_dai *)tplg->pos; | ||
1786 | if (be->size != sizeof(*be)) { | ||
1787 | dev_err(tplg->dev, "ASoC: invalid BE DAI size\n"); | ||
1788 | return -EINVAL; | ||
1789 | } | ||
1790 | |||
1791 | soc_tplg_be_dai_config(tplg, be); | ||
1792 | tplg->pos += (sizeof(*be) + be->priv.size); | ||
1793 | } | ||
1794 | |||
1795 | dev_dbg(tplg->dev, "ASoC: Configure %d BE DAIs\n", count); | ||
1796 | return 0; | ||
1797 | } | ||
1798 | |||
1799 | |||
1693 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, | 1800 | static int soc_tplg_manifest_load(struct soc_tplg *tplg, |
1694 | struct snd_soc_tplg_hdr *hdr) | 1801 | struct snd_soc_tplg_hdr *hdr) |
1695 | { | 1802 | { |
1696 | struct snd_soc_tplg_manifest *manifest; | 1803 | struct snd_soc_tplg_manifest *manifest; |
1697 | 1804 | ||
@@ -1793,6 +1900,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg, | |||
1793 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); | 1900 | return soc_tplg_dapm_widget_elems_load(tplg, hdr); |
1794 | case SND_SOC_TPLG_TYPE_PCM: | 1901 | case SND_SOC_TPLG_TYPE_PCM: |
1795 | return soc_tplg_pcm_elems_load(tplg, hdr); | 1902 | return soc_tplg_pcm_elems_load(tplg, hdr); |
1903 | case SND_SOC_TPLG_TYPE_BE_DAI: | ||
1904 | return soc_tplg_be_dai_elems_load(tplg, hdr); | ||
1796 | case SND_SOC_TPLG_TYPE_MANIFEST: | 1905 | case SND_SOC_TPLG_TYPE_MANIFEST: |
1797 | return soc_tplg_manifest_load(tplg, hdr); | 1906 | return soc_tplg_manifest_load(tplg, hdr); |
1798 | default: | 1907 | default: |