Commit 8c6529dbf881303920a415c2d14a500218661949

Authored by Liam Girdwood
Committed by Jaroslav Kysela
1 parent 7e2574050e

ALSA: asoc: core - add Digital Audio Interface (DAI) control functions.

This patch adds several functions for DAI control and config
and replaces the current method of calling function pointers within
the DAI struct.

Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>

Showing 2 changed files with 153 additions and 8 deletions Side-by-side Diff

... ... @@ -256,6 +256,27 @@
256 256 struct snd_ac97_bus_ops *ops, int num);
257 257 void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
258 258  
  259 +/* Digital Audio Interface clocking API.*/
  260 +int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
  261 + unsigned int freq, int dir);
  262 +
  263 +int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
  264 + int div_id, int div);
  265 +
  266 +int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
  267 + int pll_id, unsigned int freq_in, unsigned int freq_out);
  268 +
  269 +/* Digital Audio interface formatting */
  270 +int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
  271 +
  272 +int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
  273 + unsigned int mask, int slots);
  274 +
  275 +int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
  276 +
  277 +/* Digital Audio Interface mute */
  278 +int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
  279 +
259 280 /*
260 281 *Controls
261 282 */
sound/soc/soc-core.c
... ... @@ -434,8 +434,7 @@
434 434 else {
435 435 codec_dai->pop_wait = 0;
436 436 cancel_delayed_work(&socdev->delayed_work);
437   - if (codec_dai->dai_ops.digital_mute)
438   - codec_dai->dai_ops.digital_mute(codec_dai, 0);
  437 + snd_soc_dai_digital_mute(codec_dai, 0);
439 438 }
440 439 } else {
441 440 /* no delayed work - do we need to power up codec */
... ... @@ -454,8 +453,7 @@
454 453 SND_SOC_DAPM_STREAM_START);
455 454  
456 455 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
457   - if (codec_dai->dai_ops.digital_mute)
458   - codec_dai->dai_ops.digital_mute(codec_dai, 0);
  456 + snd_soc_dai_digital_mute(codec_dai, 0);
459 457  
460 458 } else {
461 459 /* codec already powered - power on widgets */
... ... @@ -467,8 +465,8 @@
467 465 snd_soc_dapm_stream_event(codec,
468 466 codec_dai->capture.stream_name,
469 467 SND_SOC_DAPM_STREAM_START);
470   - if (codec_dai->dai_ops.digital_mute)
471   - codec_dai->dai_ops.digital_mute(codec_dai, 0);
  468 +
  469 + snd_soc_dai_digital_mute(codec_dai, 0);
472 470 }
473 471 }
474 472  
... ... @@ -566,8 +564,8 @@
566 564 mutex_lock(&pcm_mutex);
567 565  
568 566 /* apply codec digital mute */
569   - if (!codec->active && codec_dai->dai_ops.digital_mute)
570   - codec_dai->dai_ops.digital_mute(codec_dai, 1);
  567 + if (!codec->active)
  568 + snd_soc_dai_digital_mute(codec_dai, 1);
571 569  
572 570 /* free any machine hw params */
573 571 if (machine->ops && machine->ops->hw_free)
... ... @@ -1702,6 +1700,132 @@
1702 1700 return snd_soc_update_bits(codec, reg, 0xffff, val);
1703 1701 }
1704 1702 EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
  1703 +
  1704 +/**
  1705 + * snd_soc_dai_set_sysclk - configure DAI system or master clock.
  1706 + * @dai: DAI
  1707 + * @clk_id: DAI specific clock ID
  1708 + * @freq: new clock frequency in Hz
  1709 + * @dir: new clock direction - input/output.
  1710 + *
  1711 + * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
  1712 + */
  1713 +int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
  1714 + unsigned int freq, int dir)
  1715 +{
  1716 + if (dai->dai_ops.set_sysclk)
  1717 + return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir);
  1718 + else
  1719 + return -EINVAL;
  1720 +}
  1721 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
  1722 +
  1723 +/**
  1724 + * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
  1725 + * @dai: DAI
  1726 + * @clk_id: DAI specific clock divider ID
  1727 + * @div: new clock divisor.
  1728 + *
  1729 + * Configures the clock dividers. This is used to derive the best DAI bit and
  1730 + * frame clocks from the system or master clock. It's best to set the DAI bit
  1731 + * and frame clocks as low as possible to save system power.
  1732 + */
  1733 +int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
  1734 + int div_id, int div)
  1735 +{
  1736 + if (dai->dai_ops.set_clkdiv)
  1737 + return dai->dai_ops.set_clkdiv(dai, div_id, div);
  1738 + else
  1739 + return -EINVAL;
  1740 +}
  1741 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
  1742 +
  1743 +/**
  1744 + * snd_soc_dai_set_pll - configure DAI PLL.
  1745 + * @dai: DAI
  1746 + * @pll_id: DAI specific PLL ID
  1747 + * @freq_in: PLL input clock frequency in Hz
  1748 + * @freq_out: requested PLL output clock frequency in Hz
  1749 + *
  1750 + * Configures and enables PLL to generate output clock based on input clock.
  1751 + */
  1752 +int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
  1753 + int pll_id, unsigned int freq_in, unsigned int freq_out)
  1754 +{
  1755 + if (dai->dai_ops.set_pll)
  1756 + return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out);
  1757 + else
  1758 + return -EINVAL;
  1759 +}
  1760 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
  1761 +
  1762 +/**
  1763 + * snd_soc_dai_set_fmt - configure DAI hardware audio format.
  1764 + * @dai: DAI
  1765 + * @clk_id: DAI specific clock ID
  1766 + * @fmt: SND_SOC_DAIFMT_ format value.
  1767 + *
  1768 + * Configures the DAI hardware format and clocking.
  1769 + */
  1770 +int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
  1771 +{
  1772 + if (dai->dai_ops.set_fmt)
  1773 + return dai->dai_ops.set_fmt(dai, fmt);
  1774 + else
  1775 + return -EINVAL;
  1776 +}
  1777 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
  1778 +
  1779 +/**
  1780 + * snd_soc_dai_set_tdm_slot - configure DAI TDM.
  1781 + * @dai: DAI
  1782 + * @mask: DAI specific mask representing used slots.
  1783 + * @slots: Number of slots in use.
  1784 + *
  1785 + * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
  1786 + * specific.
  1787 + */
  1788 +int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
  1789 + unsigned int mask, int slots)
  1790 +{
  1791 + if (dai->dai_ops.set_sysclk)
  1792 + return dai->dai_ops.set_tdm_slot(dai, mask, slots);
  1793 + else
  1794 + return -EINVAL;
  1795 +}
  1796 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
  1797 +
  1798 +/**
  1799 + * snd_soc_dai_set_tristate - configure DAI system or master clock.
  1800 + * @dai: DAI
  1801 + * @tristate: tristate enable
  1802 + *
  1803 + * Tristates the DAI so that others can use it.
  1804 + */
  1805 +int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
  1806 +{
  1807 + if (dai->dai_ops.set_sysclk)
  1808 + return dai->dai_ops.set_tristate(dai, tristate);
  1809 + else
  1810 + return -EINVAL;
  1811 +}
  1812 +EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
  1813 +
  1814 +/**
  1815 + * snd_soc_dai_digital_mute - configure DAI system or master clock.
  1816 + * @dai: DAI
  1817 + * @mute: mute enable
  1818 + *
  1819 + * Mutes the DAI DAC.
  1820 + */
  1821 +int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
  1822 +{
  1823 + if (dai->dai_ops.digital_mute)
  1824 + return dai->dai_ops.digital_mute(dai, mute);
  1825 + else
  1826 + return -EINVAL;
  1827 +}
  1828 +EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1705 1829  
1706 1830 static int __devinit snd_soc_init(void)
1707 1831 {