Unverified Commit 7342db3c authored by Viorel Suman's avatar Viorel Suman Committed by Mark Brown
Browse files

ASoC: ak4458: enable daisy chain



Enable Daisy Chain if in TDM mode and the number of played
channels is bigger than the maximum supported number of channels.

Signed-off-by: default avatarViorel Suman <viorel.suman@nxp.com>
Signed-off-by: default avatarShengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1618915453-29445-1-git-send-email-shengjiu.wang@nxp.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent ec1af6c6
Loading
Loading
Loading
Loading
+31 −16
Original line number Diff line number Diff line
@@ -306,6 +306,20 @@ static const struct snd_soc_dapm_route ak4497_intercon[] = {

};

static int ak4458_get_tdm_mode(struct ak4458_priv *ak4458)
{
	switch (ak4458->slots * ak4458->slot_width) {
	case 128:
		return 1;
	case 256:
		return 2;
	case 512:
		return 3;
	default:
		return 0;
	}
}

static int ak4458_rstn_control(struct snd_soc_component *component, int bit)
{
	int ret;
@@ -333,13 +347,16 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
	struct snd_soc_component *component = dai->component;
	struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
	int pcm_width = max(params_physical_width(params), ak4458->slot_width);
	u8 format, dsdsel0, dsdsel1;
	int nfs1, dsd_bclk, ret;
	u8 format, dsdsel0, dsdsel1, dchn;
	int nfs1, dsd_bclk, ret, channels, channels_max;

	nfs1 = params_rate(params);
	ak4458->fs = nfs1;

	/* calculate bit clock */
	channels = params_channels(params);
	channels_max = dai->driver->playback.channels_max;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_DSD_U8:
	case SNDRV_PCM_FORMAT_DSD_U16_LE:
@@ -419,6 +436,17 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
	snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
			    AK4458_DIF_MASK, format);

	/*
	 * Enable/disable Daisy Chain if in TDM mode and the number of played
	 * channels is bigger than the maximum supported number of channels
	 */
	dchn = ak4458_get_tdm_mode(ak4458) &&
		(ak4458->fmt == SND_SOC_DAIFMT_DSP_B) &&
		(channels > channels_max) ? AK4458_DCHAIN_MASK : 0;

	snd_soc_component_update_bits(component, AK4458_0B_CONTROL7,
				      AK4458_DCHAIN_MASK, dchn);

	ret = ak4458_rstn_control(component, 0);
	if (ret)
		return ret;
@@ -519,20 +547,7 @@ static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
	ak4458->slots = slots;
	ak4458->slot_width = slot_width;

	switch (slots * slot_width) {
	case 128:
		mode = AK4458_MODE_TDM128;
		break;
	case 256:
		mode = AK4458_MODE_TDM256;
		break;
	case 512:
		mode = AK4458_MODE_TDM512;
		break;
	default:
		mode = AK4458_MODE_NORMAL;
		break;
	}
	mode = ak4458_get_tdm_mode(ak4458) << AK4458_MODE_SHIFT;

	snd_soc_component_update_bits(component, AK4458_0A_CONTROL6,
			    AK4458_MODE_MASK,
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@
 * */
#define AK4458_ATS_SHIFT	6
#define AK4458_ATS_MASK		GENMASK(7, 6)
#define AK4458_DCHAIN_MASK	(0x1 << 1)

#define AK4458_DSDSEL_MASK		(0x1 << 0)
#define AK4458_DP_MASK			(0x1 << 7)