From 28ed9a1fcd6321644fdde0a79f4463c22006359e Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 26 Jan 2018 10:53:08 +0800 Subject: [PATCH] MLK-17462-2: ASoC: ak5558: support SND_SOC_DAIFMT_DSP_B format for TDM Add set_tdm_slot function for TDM mode, and support SND_SOC_DAIFMT_DSP_B format Signed-off-by: Shengjiu Wang --- sound/soc/codecs/ak5558.c | 51 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/ak5558.c b/sound/soc/codecs/ak5558.c index 27b771138517..f09fb9d9e480 100644 --- a/sound/soc/codecs/ak5558.c +++ b/sound/soc/codecs/ak5558.c @@ -45,6 +45,8 @@ struct ak5558_priv { int fs; /* Sampling Frequency */ int rclk; /* Master Clock */ int pdn_gpio; /* Power on / Reset GPIO */ + int slots; + int slot_width; }; /* ak5558 register cache & default register settings */ @@ -402,6 +404,7 @@ static int ak5558_hw_params(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = dai->codec; struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec); u8 bits; + int pcm_width = max(params_physical_width(params), ak5558->slot_width); dev_dbg(dai->dev, "%s(%d)\n", __func__, __LINE__); @@ -409,12 +412,11 @@ static int ak5558_hw_params(struct snd_pcm_substream *substream, bits = snd_soc_read(codec, AK5558_02_CONTROL1); bits &= ~AK5558_BITS; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - case SNDRV_PCM_FORMAT_S24_LE: + switch (pcm_width) { + case 16: bits |= AK5558_DIF_24BIT_MODE; break; - case SNDRV_PCM_FORMAT_S32_LE: + case 32: bits |= AK5558_DIF_32BIT_MODE; break; default: @@ -478,6 +480,9 @@ static int ak5558_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) case SND_SOC_DAIFMT_LEFT_J: format |= AK5558_DIF_MSB_MODE; break; + case SND_SOC_DAIFMT_DSP_B: + format |= AK5558_DIF_MSB_MODE; + break; default: return -EINVAL; } @@ -524,6 +529,43 @@ static int ak5558_set_bias_level(struct snd_soc_codec *codec, return 0; } +static int ak5558_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, + int slot_width) +{ + struct snd_soc_codec *codec = dai->codec; + struct ak5558_priv *ak5558 = snd_soc_codec_get_drvdata(codec); + int tdm_mode = 0; + int reg; + + ak5558->slots = slots; + ak5558->slot_width = slot_width; + + switch (slots * slot_width) { + case 128: + tdm_mode = 1; + break; + case 256: + tdm_mode = 2; + break; + case 512: + tdm_mode = 3; + break; + default: + tdm_mode = 0; + break; + } + + reg = snd_soc_read(codec, AK5558_03_CONTROL2); + reg &= ~(0x3 << 5); + reg |= tdm_mode << 5; + snd_soc_write(codec, AK5558_03_CONTROL2, reg); + + return 0; +} + + + #define AK5558_RATES SNDRV_PCM_RATE_8000_192000 #define AK5558_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ @@ -559,6 +601,7 @@ static struct snd_soc_dai_ops ak5558_dai_ops = { .set_sysclk = ak5558_set_dai_sysclk, .set_fmt = ak5558_set_dai_fmt, .digital_mute = ak5558_set_dai_mute, + .set_tdm_slot = ak5558_set_tdm_slot, }; static struct snd_soc_dai_driver ak5558_dai = { -- 2.17.1