Unverified Commit c43ec509 authored by Sugar Zhang's avatar Sugar Zhang Committed by Mark Brown
Browse files

ASoC: rockchip: spdif: Add support for format S32_LE



Treat 32 bit sample width as if it was 24 bits using only the
24 most significant bits.

[I've merged the channel-swapping fix from Zohn Ni into Sugar Zhang's
patch introducing the problem in the first place]

Co-developed-by: default avatarZohn Ni <zohn.ni@rock-chips.com>
Signed-off-by: default avatarZohn Ni <zohn.ni@rock-chips.com>
Signed-off-by: default avatarSugar Zhang <sugar.zhang@rock-chips.com>
Signed-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
Link: https://patch.msgid.link/20260203-rockchip-spdif-cleanup-and-bsp-sync-v2-8-4412016cf577@collabora.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 29808278
Loading
Loading
Loading
Loading
+20 −2
Original line number Diff line number Diff line
@@ -99,21 +99,38 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		val |= SPDIF_CFGR_VDW_16;
		val |= SPDIF_CFGR_ADJ_RIGHT_J;
		break;
	case SNDRV_PCM_FORMAT_S20_3LE:
		val |= SPDIF_CFGR_VDW_20;
		val |= SPDIF_CFGR_ADJ_RIGHT_J;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		val |= SPDIF_CFGR_VDW_24;
		val |= SPDIF_CFGR_ADJ_RIGHT_J;
		break;
	case SNDRV_PCM_FORMAT_S32_LE:
		val |= SPDIF_CFGR_VDW_24;
		val |= SPDIF_CFGR_ADJ_LEFT_J;
		break;
	default:
		return -EINVAL;
	}

	/*
	 * clear MCLK domain logic before setting Fmclk and Fsdo to ensure
	 * that switching between S16_LE and S32_LE audio does not result
	 * in accidential channels swap.
	 */
	regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLR_MASK,
			   SPDIF_CFGR_CLR_EN);
	udelay(1);

	ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
				 SPDIF_CFGR_CLK_DIV_MASK |
				 SPDIF_CFGR_HALFWORD_ENABLE |
				 SDPIF_CFGR_VDW_MASK, val);
				 SDPIF_CFGR_VDW_MASK |
				 SPDIF_CFGR_ADJ_MASK, val);

	return ret;
}
@@ -203,7 +220,8 @@ static struct snd_soc_dai_driver rk_spdif_dai = {
		.rates = SNDRV_PCM_RATE_8000_192000,
		.formats = (SNDRV_PCM_FMTBIT_S16_LE |
			    SNDRV_PCM_FMTBIT_S20_3LE |
			    SNDRV_PCM_FMTBIT_S24_LE),
			    SNDRV_PCM_FMTBIT_S24_LE |
			    SNDRV_PCM_FMTBIT_S32_LE),
	},
	.ops = &rk_spdif_dai_ops,
};
+8 −0
Original line number Diff line number Diff line
@@ -17,6 +17,14 @@
#define SPDIF_CFGR_CLK_DIV_MASK		(0xff << SPDIF_CFGR_CLK_DIV_SHIFT)
#define SPDIF_CFGR_CLK_DIV(x)		((x-1) << SPDIF_CFGR_CLK_DIV_SHIFT)

#define SPDIF_CFGR_CLR_MASK		BIT(7)
#define SPDIF_CFGR_CLR_EN		BIT(7)
#define SPDIF_CFGR_CLR_DIS		0

#define SPDIF_CFGR_ADJ_MASK		BIT(3)
#define SPDIF_CFGR_ADJ_LEFT_J		BIT(3)
#define SPDIF_CFGR_ADJ_RIGHT_J		0

#define SPDIF_CFGR_HALFWORD_SHIFT	2
#define SPDIF_CFGR_HALFWORD_DISABLE	(0 << SPDIF_CFGR_HALFWORD_SHIFT)
#define SPDIF_CFGR_HALFWORD_ENABLE	(1 << SPDIF_CFGR_HALFWORD_SHIFT)