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:
@ -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*/
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user