diff options
-rw-r--r-- | include/sound/soc.h | 21 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 140 |
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); |
257 | void snd_soc_free_ac97_codec(struct snd_soc_codec *codec); | 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 | *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 | } |
1704 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); | 1702 | EXPORT_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 | */ | ||
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); | ||
1829 | |||
1706 | static int __devinit snd_soc_init(void) | 1830 | static 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); |