aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Girdwood <lg@opensource.wolfsonmicro.com>2008-07-08 08:19:13 -0400
committerJaroslav Kysela <perex@perex.cz>2008-07-10 03:32:50 -0400
commit8c6529dbf881303920a415c2d14a500218661949 (patch)
tree63795a932b871c635a7a77c87ed31254f8039a24
parent7e2574050e6af203f0c94915c98c53ce1fc48044 (diff)
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>
-rw-r--r--include/sound/soc.h21
-rw-r--r--sound/soc/soc-core.c140
2 files changed, 153 insertions, 8 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 778e57e74dc8..1890d87c5204 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -256,6 +256,27 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
256 struct snd_ac97_bus_ops *ops, int num); 256 struct snd_ac97_bus_ops *ops, int num);
257void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); 257void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
258 258
259/* Digital Audio Interface clocking API.*/
260int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
261 unsigned int freq, int dir);
262
263int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
264 int div_id, int div);
265
266int 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 */
270int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
271
272int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
273 unsigned int mask, int slots);
274
275int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
276
277/* Digital Audio Interface mute */
278int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
279
259/* 280/*
260 *Controls 281 *Controls
261 */ 282 */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4d626b47b2ff..83f1190293a8 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -434,8 +434,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
434 else { 434 else {
435 codec_dai->pop_wait = 0; 435 codec_dai->pop_wait = 0;
436 cancel_delayed_work(&socdev->delayed_work); 436 cancel_delayed_work(&socdev->delayed_work);
437 if (codec_dai->dai_ops.digital_mute) 437 snd_soc_dai_digital_mute(codec_dai, 0);
438 codec_dai->dai_ops.digital_mute(codec_dai, 0);
439 } 438 }
440 } else { 439 } else {
441 /* no delayed work - do we need to power up codec */ 440 /* no delayed work - do we need to power up codec */
@@ -454,8 +453,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
454 SND_SOC_DAPM_STREAM_START); 453 SND_SOC_DAPM_STREAM_START);
455 454
456 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); 455 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
457 if (codec_dai->dai_ops.digital_mute) 456 snd_soc_dai_digital_mute(codec_dai, 0);
458 codec_dai->dai_ops.digital_mute(codec_dai, 0);
459 457
460 } else { 458 } else {
461 /* codec already powered - power on widgets */ 459 /* codec already powered - power on widgets */
@@ -467,8 +465,8 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
467 snd_soc_dapm_stream_event(codec, 465 snd_soc_dapm_stream_event(codec,
468 codec_dai->capture.stream_name, 466 codec_dai->capture.stream_name,
469 SND_SOC_DAPM_STREAM_START); 467 SND_SOC_DAPM_STREAM_START);
470 if (codec_dai->dai_ops.digital_mute) 468
471 codec_dai->dai_ops.digital_mute(codec_dai, 0); 469 snd_soc_dai_digital_mute(codec_dai, 0);
472 } 470 }
473 } 471 }
474 472
@@ -566,8 +564,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
566 mutex_lock(&pcm_mutex); 564 mutex_lock(&pcm_mutex);
567 565
568 /* apply codec digital mute */ 566 /* apply codec digital mute */
569 if (!codec->active && codec_dai->dai_ops.digital_mute) 567 if (!codec->active)
570 codec_dai->dai_ops.digital_mute(codec_dai, 1); 568 snd_soc_dai_digital_mute(codec_dai, 1);
571 569
572 /* free any machine hw params */ 570 /* free any machine hw params */
573 if (machine->ops && machine->ops->hw_free) 571 if (machine->ops && machine->ops->hw_free)
@@ -1703,6 +1701,132 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
1703} 1701}
1704EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 1702EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1705 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 */
1713int 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}
1721EXPORT_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 */
1733int 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}
1741EXPORT_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 */
1752int 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}
1760EXPORT_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 */
1770int 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}
1777EXPORT_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 */
1788int 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}
1796EXPORT_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 */
1805int 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}
1812EXPORT_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 */
1821int 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}
1828EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1829
1706static int __devinit snd_soc_init(void) 1830static int __devinit snd_soc_init(void)
1707{ 1831{
1708 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 1832 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);