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

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.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent ec1af6c6
...@@ -306,6 +306,20 @@ static const struct snd_soc_dapm_route ak4497_intercon[] = { ...@@ -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) static int ak4458_rstn_control(struct snd_soc_component *component, int bit)
{ {
int ret; int ret;
...@@ -333,13 +347,16 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream, ...@@ -333,13 +347,16 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component); struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
int pcm_width = max(params_physical_width(params), ak4458->slot_width); int pcm_width = max(params_physical_width(params), ak4458->slot_width);
u8 format, dsdsel0, dsdsel1; u8 format, dsdsel0, dsdsel1, dchn;
int nfs1, dsd_bclk, ret; int nfs1, dsd_bclk, ret, channels, channels_max;
nfs1 = params_rate(params); nfs1 = params_rate(params);
ak4458->fs = nfs1; ak4458->fs = nfs1;
/* calculate bit clock */ /* calculate bit clock */
channels = params_channels(params);
channels_max = dai->driver->playback.channels_max;
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_DSD_U8: case SNDRV_PCM_FORMAT_DSD_U8:
case SNDRV_PCM_FORMAT_DSD_U16_LE: case SNDRV_PCM_FORMAT_DSD_U16_LE:
...@@ -419,6 +436,17 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream, ...@@ -419,6 +436,17 @@ static int ak4458_hw_params(struct snd_pcm_substream *substream,
snd_soc_component_update_bits(component, AK4458_00_CONTROL1, snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
AK4458_DIF_MASK, format); 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); ret = ak4458_rstn_control(component, 0);
if (ret) if (ret)
return ret; return ret;
...@@ -519,20 +547,7 @@ static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, ...@@ -519,20 +547,7 @@ static int ak4458_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
ak4458->slots = slots; ak4458->slots = slots;
ak4458->slot_width = slot_width; ak4458->slot_width = slot_width;
switch (slots * slot_width) { mode = ak4458_get_tdm_mode(ak4458) << AK4458_MODE_SHIFT;
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;
}
snd_soc_component_update_bits(component, AK4458_0A_CONTROL6, snd_soc_component_update_bits(component, AK4458_0A_CONTROL6,
AK4458_MODE_MASK, AK4458_MODE_MASK,
......
...@@ -82,6 +82,7 @@ ...@@ -82,6 +82,7 @@
* */ * */
#define AK4458_ATS_SHIFT 6 #define AK4458_ATS_SHIFT 6
#define AK4458_ATS_MASK GENMASK(7, 6) #define AK4458_ATS_MASK GENMASK(7, 6)
#define AK4458_DCHAIN_MASK (0x1 << 1)
#define AK4458_DSDSEL_MASK (0x1 << 0) #define AK4458_DSDSEL_MASK (0x1 << 0)
#define AK4458_DP_MASK (0x1 << 7) #define AK4458_DP_MASK (0x1 << 7)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment