MLK-23567-2 ASoC: fsl_xcvr: enable SPDIF TX

Enable XCVR SPDIF TX mode.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
This commit is contained in:
Viorel Suman
2020-04-16 14:43:32 +03:00
parent 7882f7f139
commit b164260078
2 changed files with 208 additions and 140 deletions

View File

@ -11,6 +11,8 @@
#include <linux/regmap.h>
#include <linux/reset.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_iec958.h>
#include <sound/pcm_params.h>
#include "fsl_xcvr.h"
#include "imx-pcm.h"
@ -36,6 +38,16 @@ struct fsl_xcvr {
u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
};
static const struct fsl_xcvr_pll_conf {
u8 mfi; /* min=0x18, max=0x38 */
u32 mfn; /* signed int, 2's compl., min=0x3FFF0000, max=0x00010000 */
u32 mfd; /* unsigned int */
u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
} fsl_xcvr_pll_cfg[] = {
{ .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },
{ .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },
};
static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, }; /* one bit 6, 12 ? */
static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = {
.count = ARRAY_SIZE(fsl_xcvr_earc_channels),
@ -65,37 +77,91 @@ static const char * const fsl_xcvr_arc_mode[] = {
static const struct soc_enum fsl_xcvr_arc_mode_enum =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fsl_xcvr_arc_mode), fsl_xcvr_arc_mode);
/*
* pll_phy: pll 0; phy 1;
*/
static int fsl_xcvr_phy_write(struct fsl_xcvr *xcvr, int reg, int data, int pll_phy)
/** phy: true => phy, false => pll */
static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
{
int val;
int idx0, idx1;
u32 val, idx, tidx;
idx0 = pll_phy > 0 ? 26 : 24;
idx1 = pll_phy > 0 ? 24 : 26;
idx = BIT(phy ? 26 : 24);
tidx = BIT(phy ? 27 : 25);
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF);
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg);
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_WDATA, data);
regmap_read(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, &val);
val = ((~(val & BIT(idx0))) & BIT(idx0)) | (val & BIT(idx1)) | reg | BIT(15);
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, val);
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
do {
regmap_read(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, &val);
} while ((val & BIT(idx0)) != ((val & BIT(idx0 + 1)) >> 1));
} while ((val & idx) != ((val & tidx) >> 1));
return 0;
}
static int fsl_xcvr_en_phy(struct fsl_xcvr *xcvr, bool earc, u32 freq)
{
struct device *dev = &xcvr->pdev->dev;
u32 i, div = 0, log2;
for (i = 0; i < ARRAY_SIZE(fsl_xcvr_pll_cfg); i++) {
if (fsl_xcvr_pll_cfg[i].fout % freq == 0) {
div = fsl_xcvr_pll_cfg[i].fout / freq;
break;
}
}
if (!div || i >= ARRAY_SIZE(fsl_xcvr_pll_cfg))
return -EINVAL;
log2 = ilog2(div);
/* PLL: CTRL0: DIV_INTEGER */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0, fsl_xcvr_pll_cfg[i].mfi, 0);
/* PLL: NUMERATOR: MFN */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_NUM, fsl_xcvr_pll_cfg[i].mfn, 0);
/* PLL: DENOMINATOR: MFD */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_DEN, fsl_xcvr_pll_cfg[i].mfd, 0);
/* PLL: CTRL0_SET: HOLD_RING_OFF, POWER_UP */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
FSL_XCVR_PLL_CTRL0_HROFF | FSL_XCVR_PLL_CTRL0_PWP, 0);
udelay(25);
/* PLL: CTRL0: Clear Hold Ring Off */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_CLR,
FSL_XCVR_PLL_CTRL0_HROFF, 0);
udelay(100);
/* PLL: POSTDIV: PDIV0 */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_PDIV, log2, 0);
/* PLL: CTRL_SET: CLKMUX0_EN */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_CTRL0_SET,
FSL_XCVR_PLL_CTRL0_CM0_EN, 0);
if (earc) { /* eARC mode */
/* PHY: CTRL_SET: TX_DIFF_OE, PHY_EN */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
FSL_XCVR_PHY_CTRL_TSDIFF_OE |
FSL_XCVR_PHY_CTRL_PHY_EN, 1);
/* PHY: CTRL2_SET: EARC_TX_MODE */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL2_SET,
FSL_XCVR_PHY_CTRL2_EARC_TXMS, 1);
} else { /* SPDIF mode */
/* PHY: CTRL_SET: SPDIF_EN */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PHY_CTRL_SET,
FSL_XCVR_PHY_CTRL_SPDIF_EN, 1);
}
dev_dbg(dev, "PLL Fexp: %u, Fout: %u, mfi: %u, mfn: %u, mfd: %d, div: %u, pdiv0: %u\n",
freq, fsl_xcvr_pll_cfg[i].fout, fsl_xcvr_pll_cfg[i].mfi,
fsl_xcvr_pll_cfg[i].mfn, fsl_xcvr_pll_cfg[i].mfd, div, log2);
return 0;
}
static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
u32 m_ctl = 0, v_ctl = 0, m_isr = 0, v_isr = 0;
u32 m_ctl = 0, v_ctl = 0, m_isr = 0, v_isr = 0, val;
u32 mode = xcvr->mode & FSL_XCVR_AMODE_MASK;
int ret = 0;
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
@ -106,7 +172,7 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
}
/* configure EXT_CTRL */
switch (xcvr->mode & FSL_XCVR_AMODE_MASK) {
switch (mode) {
case FSL_XCVR_AMODE_SPDIF:
/* set SPDIF MODE */
m_ctl |= FSL_XCVR_EXT_CTRL_SPDIF_MODE;
@ -146,6 +212,24 @@ static int fsl_xcvr_prepare(struct snd_pcm_substream *substream,
return ret;
}
if (tx && mode == FSL_XCVR_AMODE_SPDIF) {
val = FSL_XCVR_TX_DPTH_CTRL_BYPASS_FEM;
val |= FSL_XCVR_TX_DPTH_CTRL_FRM_FMT;
ret = regmap_write(xcvr->regmap, FSL_XCVR_TX_DPTH_CTRL_SET, val);
if (ret < 0) {
dev_err(dai->dev, "Failed to set TX_DPTH: %d\n", ret);
return ret;
}
} else {
/* Release M0+ reset */
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
FSL_XCVR_EXT_CTRL_CORE_RESET, 0);
if (ret < 0) {
dev_err(dai->dev, "M0+ core release failed: %d\n", ret);
return ret;
}
}
return 0;
}
@ -202,45 +286,6 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream,
xcvr->streams |= BIT(substream->stream);
switch (xcvr->mode & FSL_XCVR_AMODE_MASK) {
case FSL_XCVR_AMODE_SPDIF:
if (tx) {
fsl_xcvr_phy_write(xcvr, 0x54, 0x1, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x1, 1);
fsl_xcvr_phy_write(xcvr, 0x0, 0x28, 0);
fsl_xcvr_phy_write(xcvr, 0x20, 0x60, 0);
fsl_xcvr_phy_write(xcvr, 0x30, 0x64, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x1006000, 0);
udelay(25);
fsl_xcvr_phy_write(xcvr, 0x8, 0x2000, 0);
udelay(100);
fsl_xcvr_phy_write(xcvr, 0x40, 0x5, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x20, 1);
fsl_xcvr_phy_write(xcvr, 0x74, 0x4000, 1);
}
break;
case FSL_XCVR_AMODE_EARC:
if (tx) {
fsl_xcvr_phy_write(xcvr, 0x54, 0x1, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x1, 1);
fsl_xcvr_phy_write(xcvr, 0x0, 0x28, 0);
fsl_xcvr_phy_write(xcvr, 0x20, 0x60, 0);
fsl_xcvr_phy_write(xcvr, 0x30, 0x64, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x1006000, 0);
udelay(25);
fsl_xcvr_phy_write(xcvr, 0x8, 0x2000, 0);
udelay(100);
fsl_xcvr_phy_write(xcvr, 0x40, 0x1, 0);
fsl_xcvr_phy_write(xcvr, 0x4, 0x20, 1);
fsl_xcvr_phy_write(xcvr, 0x74, 0x4000, 1);
}
break;
default:
break;
}
return 0;
}
@ -289,53 +334,65 @@ static int fsl_xcvr_hw_params(struct snd_pcm_substream *substream,
{
struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai);
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
u32 mask, val, r = params_rate(params), ch = params_channels(params);
int ret;
u32 r = params_rate(params), ch = params_channels(params);
snd_pcm_format_t f = params_format(params);
u32 reg, val, bclk = 32 * r * ch;
u32 mode = xcvr->mode & FSL_XCVR_AMODE_MASK;
int i, ret;
if (tx) {
mask = FSL_XCVR_CS_DATA_0_FS_MASK;
mask |= FSL_XCVR_CS_DATA_0_CH_MASK;
if (!tx)
return 0;
switch (r) {
case 32000: val = FSL_XCVR_CS_DATA_0_FS_32000; break;
case 44100: val = FSL_XCVR_CS_DATA_0_FS_44100; break;
case 48000: val = FSL_XCVR_CS_DATA_0_FS_48000; break;
case 64000: val = FSL_XCVR_CS_DATA_0_FS_64000; break;
case 88200: val = FSL_XCVR_CS_DATA_0_FS_88200; break;
case 96000: val = FSL_XCVR_CS_DATA_0_FS_96000; break;
case 176400: val = FSL_XCVR_CS_DATA_0_FS_176400; break;
case 192000: val = FSL_XCVR_CS_DATA_0_FS_192000; break;
default:
dev_err(dai->dev, "Unsupported rate: %u\n", r);
return -EINVAL;
}
val |= FSL_XCVR_CS_DATA_0_CH_UMLPCM;
ret = snd_pcm_create_iec958_consumer_hw_params(params,
xcvr->tx_iec958.status, ARRAY_SIZE(xcvr->tx_iec958.status));
if (ret < 0) {
dev_err(dai->dev, "Creating IEC958 CS failed %d\n", ret);
return ret;
}
/* Update TX CS data bits 0 */
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_TX_CS_DATA_0,
mask, val);
for (i = 0; i < 6; i++) {
val = (xcvr->tx_iec958.status[4 * i + 0] << 24) |
(xcvr->tx_iec958.status[4 * i + 1] << 16) |
(xcvr->tx_iec958.status[4 * i + 2] << 8) |
(xcvr->tx_iec958.status[4 * i + 3] << 0);
/* Update TX CS data bits */
ret = regmap_write(xcvr->regmap, FSL_XCVR_TX_CS_DATA_0 + 4 * i,
val);
if (ret < 0) {
dev_err(dai->dev, "Failed to set TX CS 0: %d\n", ret);
dev_err(dai->dev, "Failed to set TXCS%d: %d\n", i, ret);
return ret;
}
}
switch (ch) {
case 2: val = FSL_XCVR_CS_DATA_1_CH_2; break;
case 8: val = FSL_XCVR_CS_DATA_1_CH_8; break;
case 16: val = FSL_XCVR_CS_DATA_1_CH_16; break;
case 32: val = FSL_XCVR_CS_DATA_1_CH_32; break;
default:
dev_err(dai->dev, "Unsupported channels: %u\n", ch);
return -EINVAL;
}
switch (mode) {
case FSL_XCVR_AMODE_EARC:
bclk *= 10;
break;
case FSL_XCVR_AMODE_SPDIF:
bclk *= 2;
break;
}
/* Update TX CS data bits 1 */
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_TX_CS_DATA_1,
FSL_XCVR_CS_DATA_1_CH_MASK, val);
if (ret < 0) {
dev_err(dai->dev, "Failed to set TX CS 1: %d\n", ret);
return ret;
}
ret = fsl_xcvr_en_phy(xcvr, (mode == FSL_XCVR_AMODE_EARC), bclk);
if (ret < 0) {
dev_err(dai->dev, "Failed to set TX freq %u: %d\n", bclk, ret);
return ret;
}
/* enable/disable IEC958 encoding as function of input format */
val = FSL_XCVR_TX_DPTH_CTRL_CS_MOD;
val |= FSL_XCVR_TX_DPTH_CTRL_EN_PREAMBLE;
val |= FSL_XCVR_TX_DPTH_CTRL_EN_PARITY;
if (f == SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE)
reg = FSL_XCVR_TX_DPTH_CTRL_CLR; /* disable IEC958 encoding */
else
reg = FSL_XCVR_TX_DPTH_CTRL_SET; /* enable IEC958 encoding */
ret = regmap_write(xcvr->regmap, reg, val);
if (ret < 0) {
dev_err(dai->dev, "Failed to en/dis IEC958 encode: %d\n", ret);
return ret;
}
return 0;
@ -356,10 +413,9 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
switch (xcvr->mode & FSL_XCVR_AMODE_MASK) {
case FSL_XCVR_AMODE_EARC:
/* set isr_cmdc_tx_en, w1c */
ret = regmap_update_bits(xcvr->regmap,
FSL_XCVR_ISR_SET,
FSL_XCVR_ISR_CMDC_TX_EN,
FSL_XCVR_ISR_CMDC_TX_EN);
ret = regmap_write(xcvr->regmap,
FSL_XCVR_ISR_SET,
FSL_XCVR_ISR_CMDC_TX_EN);
if (ret < 0) {
dev_err(dai->dev,
"err updating isr %d\n", ret);
@ -368,9 +424,8 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
/* fall through */
case FSL_XCVR_AMODE_SPDIF:
ret = regmap_update_bits(xcvr->regmap,
ret = regmap_write(xcvr->regmap,
FSL_XCVR_TX_DPTH_CTRL_SET,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to set TX_DPTH_CTRL_STRT_DATA_TX: %d\n", ret);
@ -378,26 +433,6 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
}
break;
}
} else {
/* Clear RX FIFO */
ret = regmap_update_bits(xcvr->regmap,
FSL_XCVR_RX_DPTH_CTRL_SET,
FSL_XCVR_RX_DPTH_CTRL_CLR_RX_FIFO,
FSL_XCVR_RX_DPTH_CTRL_CLR_RX_FIFO);
if (ret < 0) {
dev_err(dai->dev, "Failed to clear RX FIFO: %d\n", ret);
return ret;
}
/* Flip RX FIFO bits */
ret = regmap_update_bits(xcvr->regmap,
FSL_XCVR_RX_DPTH_CTRL_SET,
FSL_XCVR_RX_DPTH_CTRL_STORE_FMT,
FSL_XCVR_RX_DPTH_CTRL_STORE_FMT);
if (ret < 0) {
dev_err(dai->dev, "Failed to set reverse bit in RX FIFO: %d\n", ret);
return ret;
}
}
/* enable DMA RD/WR */
@ -423,9 +458,8 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
if (tx) {
switch (xcvr->mode & FSL_XCVR_AMODE_MASK) {
case FSL_XCVR_AMODE_SPDIF:
ret = regmap_update_bits(xcvr->regmap,
ret = regmap_write(xcvr->regmap,
FSL_XCVR_TX_DPTH_CTRL_CLR,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX,
FSL_XCVR_TX_DPTH_CTRL_STRT_DATA_TX);
if (ret < 0) {
dev_err(dai->dev, "Failed to clr TX_DPTH_CTRL_STRT_DATA_TX: %d\n", ret);
@ -434,10 +468,9 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd,
/* fall through ...*/
case FSL_XCVR_AMODE_EARC:
/* clear ISR_CMDC_TX_EN, W1C */
ret = regmap_update_bits(xcvr->regmap,
FSL_XCVR_ISR_CLR,
FSL_XCVR_ISR_CMDC_TX_EN,
FSL_XCVR_ISR_CMDC_TX_EN);
ret = regmap_write(xcvr->regmap,
FSL_XCVR_ISR_CLR,
FSL_XCVR_ISR_CMDC_TX_EN);
if (ret < 0) {
dev_err(dai->dev,
"Err updating ISR %d\n", ret);
@ -521,9 +554,29 @@ err_firmware:
return ret;
}
/* Flip RX FIFO bits */
ret = regmap_write(xcvr->regmap, FSL_XCVR_RX_DPTH_CTRL_SET,
FSL_XCVR_RX_DPTH_CTRL_STORE_FMT);
if (ret < 0) {
dev_err(dev, "Failed to set reverse bit in RX FIFO: %d\n", ret);
return ret;
}
/* Store Capabilities Data Structure into Data RAM */
memcpy_toio(xcvr->ram_addr + FSL_XCVR_CAP_DATA_STR, xcvr->cap_ds,
FSL_XCVR_CAPDS_SIZE);
/* Release AI interface from reset */
ret = regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET,
FSL_XCVR_PHY_AI_CTRL_AI_RESETN);
if (ret < 0) {
dev_err(dev, "Error while setting IER0: %d\n", ret);
return ret;
}
/* PLL: BANDGAP_SET: EN_VBG (enable bandgap) */
fsl_xcvr_ai_write(xcvr, FSL_XCVR_PLL_BANDGAP_SET,
FSL_XCVR_PLL_BANDGAP_EN_VBG, 0);
return 0;
}
@ -716,7 +769,8 @@ static const struct snd_soc_pcm_stream playback = {
.rate_min = 32000,
.rate_max = 1536000,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_XCVR_FORMATS,
.formats = SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
};
static const struct snd_soc_pcm_stream capture = {
@ -726,7 +780,7 @@ static const struct snd_soc_pcm_stream capture = {
.rate_min = 32000,
.rate_max = 1536000,
.rates = SNDRV_PCM_RATE_KNOT,
.formats = FSL_XCVR_FORMATS,
.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
};
static struct snd_soc_dai_driver fsl_xcvr_dai = {
@ -1198,14 +1252,6 @@ static int fsl_xcvr_runtime_resume(struct device *dev)
return ret;
}
/* Release M0+ reset */
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
FSL_XCVR_EXT_CTRL_CORE_RESET, 0);
if (ret < 0) {
dev_err(dev, "Failed to release M0+ core: %d\n", ret);
return ret;
}
return 0;
}
#endif /* CONFIG_PM*/

View File

@ -8,10 +8,6 @@
#ifndef __FSL_XCVR_H
#define __FSL_XCVR_H
#define FSL_XCVR_FORMATS (SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
#define FSL_XCVR_AMODE_SPDIF (0x00 << 2)
#define FSL_XCVR_AMODE_SPDIF (0x00 << 2)
#define FSL_XCVR_AMODE_ARC (0x01 << 2)
#define FSL_XCVR_AMODE_EARC (0x02 << 2)
@ -211,6 +207,32 @@
#define FSL_XCVR_TX_DPTH_CTRL_CLK_RATIO BIT(29)
#define FSL_XCVR_TX_DPTH_CTRL_TM_NO_PRE_BME GENMASK(31,30)
#define FSL_XCVR_PHY_AI_CTRL_AI_RESETN BIT(15)
#define FSL_XCVR_PLL_CTRL0 0x00
#define FSL_XCVR_PLL_CTRL0_SET 0x04
#define FSL_XCVR_PLL_CTRL0_CLR 0x08
#define FSL_XCVR_PLL_NUM 0x20
#define FSL_XCVR_PLL_DEN 0x30
#define FSL_XCVR_PLL_PDIV 0x40
#define FSL_XCVR_PLL_BANDGAP_SET 0x54
#define FSL_XCVR_PHY_CTRL 0x00
#define FSL_XCVR_PHY_CTRL_SET 0x04
#define FSL_XCVR_PHY_CTRL_CLR 0x08
#define FSL_XCVR_PHY_CTRL2 0x70
#define FSL_XCVR_PHY_CTRL2_SET 0x74
#define FSL_XCVR_PHY_CTRL2_CLR 0x78
#define FSL_XCVR_PLL_BANDGAP_EN_VBG BIT(0)
#define FSL_XCVR_PLL_CTRL0_HROFF BIT(13)
#define FSL_XCVR_PLL_CTRL0_PWP BIT(14)
#define FSL_XCVR_PLL_CTRL0_CM0_EN BIT(24)
#define FSL_XCVR_PHY_CTRL_PHY_EN BIT(0)
#define FSL_XCVR_PHY_CTRL_TSDIFF_OE BIT(5)
#define FSL_XCVR_PHY_CTRL_SPDIF_EN BIT(8)
#define FSL_XCVR_PHY_CTRL2_EARC_TXMS BIT(14)
#define FSL_XCVR_CS_DATA_0_FS_MASK GENMASK(31,24)
#define FSL_XCVR_CS_DATA_0_FS_32000 0x3000000
#define FSL_XCVR_CS_DATA_0_FS_44100 0x0000000