ASoC: fsl_spdif: add support for enabling raw capture mode
Since i.MX8MM SPDIF interface is able to capture raw data. Add support in SPDIF driver for this functionality. Signed-off-by: Viorel Suman <viorel.suman@nxp.com> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com> Link: https://lore.kernel.org/r/1619425444-8666-1-git-send-email-shengjiu.wang@nxp.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
3f0d23e849
commit
604e517844
@ -49,6 +49,7 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
|
|||||||
* @imx: for imx platform
|
* @imx: for imx platform
|
||||||
* @shared_root_clock: flag of sharing a clock source with others;
|
* @shared_root_clock: flag of sharing a clock source with others;
|
||||||
* so the driver shouldn't set root clock rate
|
* so the driver shouldn't set root clock rate
|
||||||
|
* @raw_capture_mode: if raw capture mode support
|
||||||
* @interrupts: interrupt number
|
* @interrupts: interrupt number
|
||||||
* @tx_burst: tx maxburst size
|
* @tx_burst: tx maxburst size
|
||||||
* @rx_burst: rx maxburst size
|
* @rx_burst: rx maxburst size
|
||||||
@ -57,6 +58,7 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0xa, 0xb };
|
|||||||
struct fsl_spdif_soc_data {
|
struct fsl_spdif_soc_data {
|
||||||
bool imx;
|
bool imx;
|
||||||
bool shared_root_clock;
|
bool shared_root_clock;
|
||||||
|
bool raw_capture_mode;
|
||||||
u32 interrupts;
|
u32 interrupts;
|
||||||
u32 tx_burst;
|
u32 tx_burst;
|
||||||
u32 rx_burst;
|
u32 rx_burst;
|
||||||
@ -136,6 +138,7 @@ struct fsl_spdif_priv {
|
|||||||
static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
|
static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
|
||||||
.imx = false,
|
.imx = false,
|
||||||
.shared_root_clock = false,
|
.shared_root_clock = false,
|
||||||
|
.raw_capture_mode = false,
|
||||||
.interrupts = 1,
|
.interrupts = 1,
|
||||||
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
||||||
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
||||||
@ -145,6 +148,7 @@ static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
|
|||||||
static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
|
static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
|
||||||
.imx = true,
|
.imx = true,
|
||||||
.shared_root_clock = false,
|
.shared_root_clock = false,
|
||||||
|
.raw_capture_mode = false,
|
||||||
.interrupts = 1,
|
.interrupts = 1,
|
||||||
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
||||||
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
||||||
@ -154,6 +158,7 @@ static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
|
|||||||
static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
|
static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
|
||||||
.imx = true,
|
.imx = true,
|
||||||
.shared_root_clock = true,
|
.shared_root_clock = true,
|
||||||
|
.raw_capture_mode = false,
|
||||||
.interrupts = 1,
|
.interrupts = 1,
|
||||||
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
||||||
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
||||||
@ -164,12 +169,23 @@ static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
|
|||||||
static struct fsl_spdif_soc_data fsl_spdif_imx8qm = {
|
static struct fsl_spdif_soc_data fsl_spdif_imx8qm = {
|
||||||
.imx = true,
|
.imx = true,
|
||||||
.shared_root_clock = true,
|
.shared_root_clock = true,
|
||||||
|
.raw_capture_mode = false,
|
||||||
.interrupts = 2,
|
.interrupts = 2,
|
||||||
.tx_burst = 2, /* Applied for EDMA */
|
.tx_burst = 2, /* Applied for EDMA */
|
||||||
.rx_burst = 2, /* Applied for EDMA */
|
.rx_burst = 2, /* Applied for EDMA */
|
||||||
.tx_formats = SNDRV_PCM_FMTBIT_S24_LE, /* Applied for EDMA */
|
.tx_formats = SNDRV_PCM_FMTBIT_S24_LE, /* Applied for EDMA */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct fsl_spdif_soc_data fsl_spdif_imx8mm = {
|
||||||
|
.imx = true,
|
||||||
|
.shared_root_clock = false,
|
||||||
|
.raw_capture_mode = true,
|
||||||
|
.interrupts = 1,
|
||||||
|
.tx_burst = FSL_SPDIF_TXFIFO_WML,
|
||||||
|
.rx_burst = FSL_SPDIF_RXFIFO_WML,
|
||||||
|
.tx_formats = FSL_SPDIF_FORMATS_PLAYBACK,
|
||||||
|
};
|
||||||
|
|
||||||
/* Check if clk is a root clock that does not share clock source with others */
|
/* Check if clk is a root clock that does not share clock source with others */
|
||||||
static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, int clk)
|
static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, int clk)
|
||||||
{
|
{
|
||||||
@ -846,6 +862,39 @@ static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fsl_spdif_rx_rcm_get(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
|
||||||
|
struct regmap *regmap = spdif_priv->regmap;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
regmap_read(regmap, REG_SPDIF_SCR, &val);
|
||||||
|
val = (val & SCR_RAW_CAPTURE_MODE) ? 1 : 0;
|
||||||
|
ucontrol->value.integer.value[0] = val;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fsl_spdif_rx_rcm_put(struct snd_kcontrol *kcontrol,
|
||||||
|
struct snd_ctl_elem_value *ucontrol)
|
||||||
|
{
|
||||||
|
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
|
||||||
|
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
|
||||||
|
struct regmap *regmap = spdif_priv->regmap;
|
||||||
|
u32 val = (ucontrol->value.integer.value[0] ? SCR_RAW_CAPTURE_MODE : 0);
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
cpu_dai->driver->capture.formats |= SNDRV_PCM_FMTBIT_S32_LE;
|
||||||
|
else
|
||||||
|
cpu_dai->driver->capture.formats &= ~SNDRV_PCM_FMTBIT_S32_LE;
|
||||||
|
|
||||||
|
regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_RAW_CAPTURE_MODE, val);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* DPLL lock information */
|
/* DPLL lock information */
|
||||||
static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
|
static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
|
||||||
struct snd_ctl_elem_info *uinfo)
|
struct snd_ctl_elem_info *uinfo)
|
||||||
@ -1029,6 +1078,19 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_kcontrol_new fsl_spdif_ctrls_rcm[] = {
|
||||||
|
{
|
||||||
|
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
|
||||||
|
.name = "IEC958 Raw Capture Mode",
|
||||||
|
.access = SNDRV_CTL_ELEM_ACCESS_READ |
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_WRITE |
|
||||||
|
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
|
||||||
|
.info = snd_ctl_boolean_mono_info,
|
||||||
|
.get = fsl_spdif_rx_rcm_get,
|
||||||
|
.put = fsl_spdif_rx_rcm_put,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
|
static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
|
||||||
{
|
{
|
||||||
struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
|
struct fsl_spdif_priv *spdif_private = snd_soc_dai_get_drvdata(dai);
|
||||||
@ -1038,6 +1100,10 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
|
|||||||
|
|
||||||
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
|
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, ARRAY_SIZE(fsl_spdif_ctrls));
|
||||||
|
|
||||||
|
if (spdif_private->soc->raw_capture_mode)
|
||||||
|
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls_rcm,
|
||||||
|
ARRAY_SIZE(fsl_spdif_ctrls_rcm));
|
||||||
|
|
||||||
/*Clear the val bit for Tx*/
|
/*Clear the val bit for Tx*/
|
||||||
regmap_update_bits(spdif_private->regmap, REG_SPDIF_SCR,
|
regmap_update_bits(spdif_private->regmap, REG_SPDIF_SCR,
|
||||||
SCR_VAL_MASK, SCR_VAL_CLEAR);
|
SCR_VAL_MASK, SCR_VAL_CLEAR);
|
||||||
@ -1476,6 +1542,7 @@ static const struct of_device_id fsl_spdif_dt_ids[] = {
|
|||||||
{ .compatible = "fsl,vf610-spdif", .data = &fsl_spdif_vf610, },
|
{ .compatible = "fsl,vf610-spdif", .data = &fsl_spdif_vf610, },
|
||||||
{ .compatible = "fsl,imx6sx-spdif", .data = &fsl_spdif_imx6sx, },
|
{ .compatible = "fsl,imx6sx-spdif", .data = &fsl_spdif_imx6sx, },
|
||||||
{ .compatible = "fsl,imx8qm-spdif", .data = &fsl_spdif_imx8qm, },
|
{ .compatible = "fsl,imx8qm-spdif", .data = &fsl_spdif_imx8qm, },
|
||||||
|
{ .compatible = "fsl,imx8mm-spdif", .data = &fsl_spdif_imx8mm, },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
|
MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#define SCR_TXFIFO_FSEL_IF4 (0x1 << SCR_TXFIFO_FSEL_OFFSET)
|
#define SCR_TXFIFO_FSEL_IF4 (0x1 << SCR_TXFIFO_FSEL_OFFSET)
|
||||||
#define SCR_TXFIFO_FSEL_IF8 (0x2 << SCR_TXFIFO_FSEL_OFFSET)
|
#define SCR_TXFIFO_FSEL_IF8 (0x2 << SCR_TXFIFO_FSEL_OFFSET)
|
||||||
#define SCR_TXFIFO_FSEL_IF12 (0x3 << SCR_TXFIFO_FSEL_OFFSET)
|
#define SCR_TXFIFO_FSEL_IF12 (0x3 << SCR_TXFIFO_FSEL_OFFSET)
|
||||||
|
#define SCR_RAW_CAPTURE_MODE BIT(14)
|
||||||
#define SCR_LOW_POWER (1 << 13)
|
#define SCR_LOW_POWER (1 << 13)
|
||||||
#define SCR_SOFT_RESET (1 << 12)
|
#define SCR_SOFT_RESET (1 << 12)
|
||||||
#define SCR_TXFIFO_CTRL_OFFSET 10
|
#define SCR_TXFIFO_CTRL_OFFSET 10
|
||||||
|
Loading…
Reference in New Issue
Block a user