ASoC: hdmi-codec: fix S/PDIF DAI

When using the S/PDIF DAI, there is no requirement to call
snd_soc_dai_set_fmt() as there is no DAI format definition that defines
S/PDIF.  In any case, S/PDIF does not have separate clocks, this is
embedded into the data stream.

Consequently, when attempting to use TDA998x in S/PDIF mode, the attempt
to configure TDA998x via the hw_params callback fails as the
hdmi_codec_daifmt is left initialised to zero.

Since the S/PDIF DAI will only be used by S/PDIF, prepare the
hdmi_codec_daifmt structure for this format.

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Reviewed-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Russell King 2019-02-28 15:30:34 +00:00 committed by Mark Brown
parent f060f46f09
commit 2e95f984aa
No known key found for this signature in database
GPG key ID: 24D68B725D5487D0

View file

@ -529,73 +529,71 @@ static int hdmi_codec_set_fmt(struct snd_soc_dai *dai,
{ {
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
struct hdmi_codec_daifmt cf = { 0 }; struct hdmi_codec_daifmt cf = { 0 };
int ret = 0;
dev_dbg(dai->dev, "%s()\n", __func__); dev_dbg(dai->dev, "%s()\n", __func__);
if (dai->id == DAI_ID_SPDIF) { if (dai->id == DAI_ID_SPDIF)
cf.fmt = HDMI_SPDIF; return 0;
} else {
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
cf.bit_clk_master = 1;
cf.frame_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFM:
cf.frame_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBM_CFS:
cf.bit_clk_master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
break;
default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_NB_NF: case SND_SOC_DAIFMT_CBM_CFM:
break; cf.bit_clk_master = 1;
case SND_SOC_DAIFMT_NB_IF: cf.frame_clk_master = 1;
cf.frame_clk_inv = 1; break;
break; case SND_SOC_DAIFMT_CBS_CFM:
case SND_SOC_DAIFMT_IB_NF: cf.frame_clk_master = 1;
cf.bit_clk_inv = 1; break;
break; case SND_SOC_DAIFMT_CBM_CFS:
case SND_SOC_DAIFMT_IB_IF: cf.bit_clk_master = 1;
cf.frame_clk_inv = 1; break;
cf.bit_clk_inv = 1; case SND_SOC_DAIFMT_CBS_CFS:
break; break;
} default:
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_I2S: case SND_SOC_DAIFMT_NB_NF:
cf.fmt = HDMI_I2S; break;
break; case SND_SOC_DAIFMT_NB_IF:
case SND_SOC_DAIFMT_DSP_A: cf.frame_clk_inv = 1;
cf.fmt = HDMI_DSP_A; break;
break; case SND_SOC_DAIFMT_IB_NF:
case SND_SOC_DAIFMT_DSP_B: cf.bit_clk_inv = 1;
cf.fmt = HDMI_DSP_B; break;
break; case SND_SOC_DAIFMT_IB_IF:
case SND_SOC_DAIFMT_RIGHT_J: cf.frame_clk_inv = 1;
cf.fmt = HDMI_RIGHT_J; cf.bit_clk_inv = 1;
break; break;
case SND_SOC_DAIFMT_LEFT_J: }
cf.fmt = HDMI_LEFT_J;
break; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_AC97: case SND_SOC_DAIFMT_I2S:
cf.fmt = HDMI_AC97; cf.fmt = HDMI_I2S;
break; break;
default: case SND_SOC_DAIFMT_DSP_A:
dev_err(dai->dev, "Invalid DAI interface format\n"); cf.fmt = HDMI_DSP_A;
return -EINVAL; break;
} case SND_SOC_DAIFMT_DSP_B:
cf.fmt = HDMI_DSP_B;
break;
case SND_SOC_DAIFMT_RIGHT_J:
cf.fmt = HDMI_RIGHT_J;
break;
case SND_SOC_DAIFMT_LEFT_J:
cf.fmt = HDMI_LEFT_J;
break;
case SND_SOC_DAIFMT_AC97:
cf.fmt = HDMI_AC97;
break;
default:
dev_err(dai->dev, "Invalid DAI interface format\n");
return -EINVAL;
} }
hcp->daifmt[dai->id] = cf; hcp->daifmt[dai->id] = cf;
return ret; return 0;
} }
static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute)
@ -792,8 +790,10 @@ static int hdmi_codec_probe(struct platform_device *pdev)
i++; i++;
} }
if (hcd->spdif) if (hcd->spdif) {
hcp->daidrv[i] = hdmi_spdif_dai; hcp->daidrv[i] = hdmi_spdif_dai;
hcp->daifmt[DAI_ID_SPDIF].fmt = HDMI_SPDIF;
}
dev_set_drvdata(dev, hcp); dev_set_drvdata(dev, hcp);