ASoC: rockchip: spdif: Add support for non-pcm switch

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Change-Id: Iff38282013c02ba312ff5f8093fd762c358bdc37
This commit is contained in:
Sugar Zhang
2025-09-08 10:27:48 +08:00
committed by Tao Huang
parent 9cb4d07e13
commit 640c4f6115
2 changed files with 58 additions and 0 deletions

View File

@@ -16,6 +16,7 @@
#include <linux/pm_runtime.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <sound/asoundef.h>
#include <sound/pcm_params.h>
#include <sound/pcm_iec958.h>
#include <sound/dmaengine_pcm.h>
@@ -58,6 +59,7 @@ struct rk_spdif_dev {
struct snd_dmaengine_dai_dma_data playback_dma_data;
struct regmap *regmap;
bool non_pcm;
};
static const struct of_device_id rk_spdif_match[] __maybe_unused = {
@@ -141,6 +143,20 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
if (spdif->non_pcm) {
cs[0] |= IEC958_AES0_NONAUDIO;
for (i = 0; i < AES_IEC958_STATUS_SIZE / 2; i++)
regmap_write(spdif->regmap, SPDIF_VLDFRn(i), 0xffffffff);
regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_VFE_MASK,
SPDIF_CFGR_VFE_EN);
} else {
cs[0] &= ~IEC958_AES0_NONAUDIO;
for (i = 0; i < AES_IEC958_STATUS_SIZE / 2; i++)
regmap_write(spdif->regmap, SPDIF_VLDFRn(i), 0x0);
regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_VFE_MASK,
SPDIF_CFGR_VFE_DIS);
}
for (i = 0; i < CS_BYTE / 2; i++)
regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i]));
@@ -275,8 +291,46 @@ static struct snd_soc_dai_driver rk_spdif_dai = {
.ops = &rk_spdif_dai_ops,
};
static const char * const non_pcm_text[] = { "pcm", "non pcm" };
static const struct soc_enum __maybe_unused non_pcm_switch =
SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(non_pcm_text), non_pcm_text);
static int rk_spdif_non_pcm_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct rk_spdif_dev *spdif = snd_soc_component_get_drvdata(component);
ucontrol->value.enumerated.item[0] = spdif->non_pcm;
return 0;
}
static int rk_spdif_non_pcm_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
struct rk_spdif_dev *spdif = snd_soc_component_get_drvdata(component);
bool non_pcm;
non_pcm = !!ucontrol->value.enumerated.item[0];
if (non_pcm == spdif->non_pcm)
return 0;
spdif->non_pcm = non_pcm;
return 1;
}
static const struct snd_kcontrol_new rk_spdif_controls[] = {
SOC_ENUM_EXT("AUDIO MODE", non_pcm_switch,
rk_spdif_non_pcm_get, rk_spdif_non_pcm_put),
};
static const struct snd_soc_component_driver rk_spdif_component = {
.name = "rockchip-spdif",
.controls = rk_spdif_controls,
.num_controls = ARRAY_SIZE(rk_spdif_controls),
.legacy_dai_naming = 1,
};

View File

@@ -25,6 +25,10 @@
#define SPDIF_CFGR_CSE_EN BIT(6)
#define SPDIF_CFGR_CSE_DIS 0
#define SPDIF_CFGR_VFE_MASK BIT(4)
#define SPDIF_CFGR_VFE_EN BIT(4)
#define SPDIF_CFGR_VFE_DIS 0
#define SPDIF_CFGR_ADJ_MASK BIT(3)
#define SPDIF_CFGR_ADJ_LEFT_J BIT(3)
#define SPDIF_CFGR_ADJ_RIGHT_J 0