diff options
author | Rongjun Ying <rongjun.ying@csr.com> | 2014-03-20 08:46:19 +0100 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-04-14 18:28:17 +0200 |
commit | b87704cef258a4f44ab1386a70b7628ec3cefd36 (patch) | |
tree | e68da26e46bdf6a8057b4aad67762d25875b22bf /sound/soc/codecs | |
parent | Linux 3.15-rc1 (diff) | |
download | linux-b87704cef258a4f44ab1386a70b7628ec3cefd36.tar.xz linux-b87704cef258a4f44ab1386a70b7628ec3cefd36.zip |
ASoC: sirf: Move the tx rx enable from port to codec, that will not need register sharing
The port driver only used to register component and dmaengine pcm.
Signed-off-by: Rongjun Ying <rongjun.ying@csr.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/sirf-audio-codec.c | 74 | ||||
-rw-r--r-- | sound/soc/codecs/sirf-audio-codec.h | 50 |
2 files changed, 116 insertions, 8 deletions
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 58e7c1f23771..c5177bc5df82 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c @@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { {"Mic input mode mux", "Differential", "MICIN1"}, }; +static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); +} + +static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); +} + +static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, + int channels) +{ + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); + regmap_write(sirf_audio_codec->regmap, + AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); + regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); + regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, + AUDIO_FIFO_START, AUDIO_FIFO_START); + if (channels == 1) + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); + else + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); +} + +static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) +{ + regmap_update_bits(sirf_audio_codec->regmap, + AUDIO_PORT_IC_CODEC_RX_CTRL, + IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); +} + static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { - int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; struct snd_soc_codec *codec = dai->codec; - u32 val = 0; + struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); + int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; /* * This is a workaround, When stop playback, @@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (playback) { + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, 0); + sirf_audio_codec_tx_disable(sirf_audio_codec); + } else + sirf_audio_codec_rx_disable(sirf_audio_codec); break; case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (playback) - val = IC_HSLEN | IC_HSREN; + if (playback) { + sirf_audio_codec_tx_enable(sirf_audio_codec); + snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, + IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); + } else + sirf_audio_codec_rx_enable(sirf_audio_codec, + substream->runtime->channels); break; default: return -EINVAL; } - if (playback) - snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, - IC_HSLEN | IC_HSREN, val); return 0; } @@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = AUDIO_IC_CODEC_CTRL3, + .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, .cache_type = REGCACHE_NONE, }; diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h index d4c187b8e54a..ba1adc03839f 100644 --- a/sound/soc/codecs/sirf-audio-codec.h +++ b/sound/soc/codecs/sirf-audio-codec.h @@ -72,4 +72,54 @@ #define IC_RXPGAR 0x7B #define IC_RXPGAL 0x7B +#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F +#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 + +#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_SC_OFFSET) +#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_LC_OFFSET) +#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_TX_FIFO_HC_OFFSET) + +#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F +#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 +#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 +#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 + +#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_SC_OFFSET) +#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_LC_OFFSET) +#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ + << AUDIO_PORT_RX_FIFO_HC_OFFSET) +#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) +#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) + +#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) +#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) +#define AUDIO_PORT_IC_TXFIFO_STS (0x0104) +#define AUDIO_PORT_IC_TXFIFO_INT (0x0108) +#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) + +#define AUDIO_PORT_IC_RXFIFO_OP (0x0110) +#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) +#define AUDIO_PORT_IC_RXFIFO_STS (0x0118) +#define AUDIO_PORT_IC_RXFIFO_INT (0x011C) +#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) + +#define AUDIO_FIFO_START (1 << 0) +#define AUDIO_FIFO_RESET (1 << 1) + +#define AUDIO_FIFO_FULL (1 << 0) +#define AUDIO_FIFO_EMPTY (1 << 1) +#define AUDIO_FIFO_OFLOW (1 << 2) +#define AUDIO_FIFO_UFLOW (1 << 3) + +#define IC_TX_ENABLE (0x03) +#define IC_RX_ENABLE_MONO (0x01) +#define IC_RX_ENABLE_STEREO (0x03) + #endif /*__SIRF_AUDIO_CODEC_H*/ |