diff options
Diffstat (limited to 'sound/soc/codecs/twl4030.c')
-rw-r--r-- | sound/soc/codecs/twl4030.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index eaf91ab465b4..e4d683daa450 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -1629,6 +1629,28 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1629 | return 0; | 1629 | return 0; |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | /* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R | ||
1633 | * (VTXL, VTXR) for uplink has to be enabled/disabled. */ | ||
1634 | static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, | ||
1635 | int enable) | ||
1636 | { | ||
1637 | u8 reg, mask; | ||
1638 | |||
1639 | reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); | ||
1640 | |||
1641 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) | ||
1642 | mask = TWL4030_ARXL1_VRX_EN; | ||
1643 | else | ||
1644 | mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN; | ||
1645 | |||
1646 | if (enable) | ||
1647 | reg |= mask; | ||
1648 | else | ||
1649 | reg &= ~mask; | ||
1650 | |||
1651 | twl4030_write(codec, TWL4030_REG_OPTION, reg); | ||
1652 | } | ||
1653 | |||
1632 | static int twl4030_voice_startup(struct snd_pcm_substream *substream, | 1654 | static int twl4030_voice_startup(struct snd_pcm_substream *substream, |
1633 | struct snd_soc_dai *dai) | 1655 | struct snd_soc_dai *dai) |
1634 | { | 1656 | { |
@@ -1665,6 +1687,17 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream, | |||
1665 | return 0; | 1687 | return 0; |
1666 | } | 1688 | } |
1667 | 1689 | ||
1690 | static void twl4030_voice_shutdown(struct snd_pcm_substream *substream, | ||
1691 | struct snd_soc_dai *dai) | ||
1692 | { | ||
1693 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1694 | struct snd_soc_device *socdev = rtd->socdev; | ||
1695 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1696 | |||
1697 | /* Enable voice digital filters */ | ||
1698 | twl4030_voice_enable(codec, substream->stream, 0); | ||
1699 | } | ||
1700 | |||
1668 | static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | 1701 | static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, |
1669 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 1702 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
1670 | { | 1703 | { |
@@ -1673,6 +1706,9 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
1673 | struct snd_soc_codec *codec = socdev->card->codec; | 1706 | struct snd_soc_codec *codec = socdev->card->codec; |
1674 | u8 old_mode, mode; | 1707 | u8 old_mode, mode; |
1675 | 1708 | ||
1709 | /* Enable voice digital filters */ | ||
1710 | twl4030_voice_enable(codec, substream->stream, 1); | ||
1711 | |||
1676 | /* bit rate */ | 1712 | /* bit rate */ |
1677 | old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) | 1713 | old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) |
1678 | & ~(TWL4030_CODECPDZ); | 1714 | & ~(TWL4030_CODECPDZ); |
@@ -1780,6 +1816,7 @@ static struct snd_soc_dai_ops twl4030_dai_ops = { | |||
1780 | 1816 | ||
1781 | static struct snd_soc_dai_ops twl4030_dai_voice_ops = { | 1817 | static struct snd_soc_dai_ops twl4030_dai_voice_ops = { |
1782 | .startup = twl4030_voice_startup, | 1818 | .startup = twl4030_voice_startup, |
1819 | .shutdown = twl4030_voice_shutdown, | ||
1783 | .hw_params = twl4030_voice_hw_params, | 1820 | .hw_params = twl4030_voice_hw_params, |
1784 | .set_sysclk = twl4030_voice_set_dai_sysclk, | 1821 | .set_sysclk = twl4030_voice_set_dai_sysclk, |
1785 | .set_fmt = twl4030_voice_set_dai_fmt, | 1822 | .set_fmt = twl4030_voice_set_dai_fmt, |