Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit e0d746cc authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown
Browse files

ASoC: da7213: add support for DSP modes



DSP modes are documented in the data sheet but not enabled in the driver.
The work-around already implemented for DA7218/9 is also required to
make sure the bit clock handling in DSP modes follows ASoC conventions.

Tested with ARD-AUDIO-DA7212 and Minnowmax Turbot boards

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Acked-by: default avatarAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 2bd6bf03
Loading
Loading
Loading
Loading
+48 −10
Original line number Diff line number Diff line
@@ -1220,6 +1220,7 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	struct snd_soc_codec *codec = codec_dai->codec;
	struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec);
	u8 dai_clk_mode = 0, dai_ctrl = 0;
	u8 dai_offset = 0;

	/* Set master/slave mode */
	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1234,6 +1235,10 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	}

	/* Set clock normal/inverted */
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
	case SND_SOC_DAIFMT_LEFT_J:
	case SND_SOC_DAIFMT_RIGHT_J:
		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			break;
@@ -1244,7 +1249,32 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
			dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
			break;
		case SND_SOC_DAIFMT_IB_IF:
		dai_clk_mode |= DA7213_DAI_WCLK_POL_INV | DA7213_DAI_CLK_POL_INV;
			dai_clk_mode |= DA7213_DAI_WCLK_POL_INV |
					DA7213_DAI_CLK_POL_INV;
			break;
		default:
			return -EINVAL;
		}
		break;
	case SND_SOC_DAI_FORMAT_DSP_A:
	case SND_SOC_DAI_FORMAT_DSP_B:
		/* The bclk is inverted wrt ASoC conventions */
		switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
		case SND_SOC_DAIFMT_NB_NF:
			dai_clk_mode |= DA7213_DAI_CLK_POL_INV;
			break;
		case SND_SOC_DAIFMT_NB_IF:
			dai_clk_mode |= DA7213_DAI_WCLK_POL_INV |
					DA7213_DAI_CLK_POL_INV;
			break;
		case SND_SOC_DAIFMT_IB_NF:
			break;
		case SND_SOC_DAIFMT_IB_IF:
			dai_clk_mode |= DA7213_DAI_WCLK_POL_INV;
			break;
		default:
			return -EINVAL;
		}
		break;
	default:
		return -EINVAL;
@@ -1261,6 +1291,13 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	case SND_SOC_DAIFMT_RIGHT_J:
		dai_ctrl |= DA7213_DAI_FORMAT_RIGHT_J;
		break;
	case SND_SOC_DAI_FORMAT_DSP_A: /* L data MSB after FRM LRC */
		dai_ctrl |= DA7213_DAI_FORMAT_DSP;
		dai_offset = 1;
		break;
	case SND_SOC_DAI_FORMAT_DSP_B: /* L data MSB during FRM LRC */
		dai_ctrl |= DA7213_DAI_FORMAT_DSP;
		break;
	default:
		return -EINVAL;
	}
@@ -1271,6 +1308,7 @@ static int da7213_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
	snd_soc_write(codec, DA7213_DAI_CLK_MODE, dai_clk_mode);
	snd_soc_update_bits(codec, DA7213_DAI_CTRL, DA7213_DAI_FORMAT_MASK,
			    dai_ctrl);
	snd_soc_write(codec, DA7213_DAI_OFFSET, dai_offset);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@
#define DA7213_DAI_FORMAT_I2S_MODE				(0x0 << 0)
#define DA7213_DAI_FORMAT_LEFT_J				(0x1 << 0)
#define DA7213_DAI_FORMAT_RIGHT_J				(0x2 << 0)
#define DA7213_DAI_FORMAT_DSP					(0x3 << 0)
#define DA7213_DAI_FORMAT_MASK					(0x3 << 0)
#define DA7213_DAI_WORD_LENGTH_S16_LE				(0x0 << 2)
#define DA7213_DAI_WORD_LENGTH_S20_LE				(0x1 << 2)