From 610e75569e835daa1cfae3f86a0027bb98c98436 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 26 Apr 2016 14:38:35 +0800 Subject: MLK-12722: ASoC: fsl_spdif: clear the validity bit for TX Validity bit is set in default, which means the data is not reliable, The receive device may drop this data. So clear it in default, and provide a mixer interface for user to control this bit. Signed-off-by: Shengjiu Wang --- sound/soc/fsl/fsl_spdif.c | 66 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 60 insertions(+), 6 deletions(-) (limited to 'sound/soc/fsl/fsl_spdif.c') diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 9dca6a1e430f..7a2a50cf06bc 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c @@ -2,7 +2,7 @@ // // Freescale S/PDIF ALSA SoC Digital Audio Interface (DAI) driver // -// Copyright (C) 2013-2015 Freescale Semiconductor, Inc. +// Copyright (C) 2013-2016 Freescale Semiconductor, Inc. // // Based on stmp3xxx_spdif_dai.c // Vladimir Barinov @@ -755,7 +755,7 @@ static int fsl_spdif_qget(struct snd_kcontrol *kcontrol, } /* Valid bit information */ -static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol, +static int fsl_spdif_rx_vbit_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; @@ -767,7 +767,7 @@ static int fsl_spdif_vbit_info(struct snd_kcontrol *kcontrol, } /* Get valid good bit from interrupt status register */ -static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol, +static int fsl_spdif_rx_vbit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol); @@ -782,6 +782,46 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol, return 0; } +static int fsl_spdif_tx_vbit_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + + return 0; +} + +static int fsl_spdif_tx_vbit_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_VAL_MASK) >> SCR_VAL_OFFSET; + val = 1 - val; + ucontrol->value.integer.value[0] = val; + + return 0; +} + +static int fsl_spdif_tx_vbit_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 = (1 - ucontrol->value.integer.value[0]) << SCR_VAL_OFFSET; + + regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK, val); + + return 0; +} + /* DPLL lock information */ static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -939,11 +979,21 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = { /* Valid bit error controller */ { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "IEC958 V-Bit Errors", + .name = "IEC958 Rx V-Bit Errors", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .info = fsl_spdif_vbit_info, - .get = fsl_spdif_vbit_get, + .info = fsl_spdif_rx_vbit_info, + .get = fsl_spdif_rx_vbit_get, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "IEC958 Tx V-Bit", + .access = SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_WRITE | + SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .info = fsl_spdif_tx_vbit_info, + .get = fsl_spdif_tx_vbit_get, + .put = fsl_spdif_tx_vbit_put, }, /* DPLL lock info get controller */ { @@ -1292,6 +1342,10 @@ static int fsl_spdif_probe(struct platform_device *pdev) spdif_priv->dma_params_tx.addr = res->start + REG_SPDIF_STL; spdif_priv->dma_params_rx.addr = res->start + REG_SPDIF_SRL; + /*Clear the val bit for Tx*/ + regmap_update_bits(spdif_priv->regmap, REG_SPDIF_SCR, + SCR_VAL_MASK, 1 << SCR_VAL_OFFSET); + /* Register with ASoC */ dev_set_drvdata(&pdev->dev, spdif_priv); -- cgit v1.2.3