[PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls

Shengjiu Wang
2026-03-30T11:26:07Z

Use the type SNDRV_CTL_ELEM_TYPE_IEC958 for iec958 channel status
controls, the original type will cause mixer-test to iterate all 32bit
values, which costs a lot of time. And using IEC958 type can reduce the
control numbers.

Also enable pm runtime before updating registers to make the regmap cache
data align with the value in hardware.

Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
sound/soc/fsl/fsl_easrc.c | 108 ++++++++++++++++++++++++++------------
1 file changed, 74 insertions(+), 34 deletions(-)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 3086cb758beb..a6c643a4d51e 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -78,17 +78,47 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol,
return 0;
}

+static int fsl_easrc_iec958_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
+ uinfo->count = 1;
+ return 0;
+}
+
static int fsl_easrc_get_reg(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
- unsigned int regval;
+ struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component);
+ unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status;
+ int ret;

- regval = snd_soc_component_read(component, mc->regbase);
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS0(mc->regbase), &regval[0]);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS1(mc->regbase), &regval[1]);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS2(mc->regbase), &regval[2]);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS3(mc->regbase), &regval[3]);
+ if (ret)
+ return ret;
+
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS4(mc->regbase), &regval[4]);
+ if (ret)
+ return ret;

- ucontrol->value.integer.value[0] = regval;
+ ret = regmap_read(easrc->regmap, REG_EASRC_CS5(mc->regbase), &regval[5]);
+ if (ret)
+ return ret;

return 0;
}
@@ -100,22 +130,52 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,
struct soc_mreg_control *mc =
(struct soc_mreg_control *)kcontrol->private_value;
struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component);
- unsigned int regval = ucontrol->value.integer.value[0];
- bool changed;
+ unsigned int *regval = (unsigned int *)ucontrol->value.iec958.status;
int ret;

- ret = regmap_update_bits_check(easrc->regmap, mc->regbase,
- GENMASK(31, 0), regval, &changed);
- if (ret != 0)
+ ret = pm_runtime_resume_and_get(component->dev);
+ if (ret)
return ret;

- return changed;
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS0(mc->regbase),
+ GENMASK(31, 0), regval[0]);
+ if (ret != 0)
+ goto err;
+
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS1(mc->regbase),
+ GENMASK(31, 0), regval[1]);
+ if (ret != 0)
+ goto err;
+
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS2(mc->regbase),
+ GENMASK(31, 0), regval[2]);
+ if (ret != 0)
+ goto err;
+
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS3(mc->regbase),
+ GENMASK(31, 0), regval[3]);
+ if (ret != 0)
+ goto err;
+
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS4(mc->regbase),
+ GENMASK(31, 0), regval[4]);
+ if (ret != 0)
+ goto err;
+
+ ret = regmap_update_bits(easrc->regmap, REG_EASRC_CS5(mc->regbase),
+ GENMASK(31, 0), regval[5]);
+ if (ret != 0)
+ goto err;
+err:
+ pm_runtime_put_autosuspend(component->dev);
+
+ return ret;
}

#define SOC_SINGLE_REG_RW(xname, xreg) \
{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = (xname), \
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
- .info = snd_soc_info_xr_sx, .get = fsl_easrc_get_reg, \
+ .info = fsl_easrc_iec958_info, .get = fsl_easrc_get_reg, \
.put = fsl_easrc_set_reg, \
.private_value = (unsigned long)&(struct soc_mreg_control) \
{ .regbase = xreg, .regcount = 1, .nbits = 32, \
@@ -146,30 +206,10 @@ static const struct snd_kcontrol_new fsl_easrc_snd_controls[] = {
SOC_SINGLE_VAL_RW("Context 2 IEC958 Bits Per Sample", 2),
SOC_SINGLE_VAL_RW("Context 3 IEC958 Bits Per Sample", 3),

- SOC_SINGLE_REG_RW("Context 0 IEC958 CS0", REG_EASRC_CS0(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS0", REG_EASRC_CS0(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS0", REG_EASRC_CS0(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS0", REG_EASRC_CS0(3)),
- SOC_SINGLE_REG_RW("Context 0 IEC958 CS1", REG_EASRC_CS1(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS1", REG_EASRC_CS1(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS1", REG_EASRC_CS1(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS1", REG_EASRC_CS1(3)),
- SOC_SINGLE_REG_RW("Context 0 IEC958 CS2", REG_EASRC_CS2(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS2", REG_EASRC_CS2(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS2", REG_EASRC_CS2(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS2", REG_EASRC_CS2(3)),
- SOC_SINGLE_REG_RW("Context 0 IEC958 CS3", REG_EASRC_CS3(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS3", REG_EASRC_CS3(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS3", REG_EASRC_CS3(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS3", REG_EASRC_CS3(3)),
- SOC_SINGLE_REG_RW("Context 0 IEC958 CS4", REG_EASRC_CS4(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS4", REG_EASRC_CS4(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS4", REG_EASRC_CS4(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS4", REG_EASRC_CS4(3)),
- SOC_SINGLE_REG_RW("Context 0 IEC958 CS5", REG_EASRC_CS5(0)),
- SOC_SINGLE_REG_RW("Context 1 IEC958 CS5", REG_EASRC_CS5(1)),
- SOC_SINGLE_REG_RW("Context 2 IEC958 CS5", REG_EASRC_CS5(2)),
- SOC_SINGLE_REG_RW("Context 3 IEC958 CS5", REG_EASRC_CS5(3)),
+ SOC_SINGLE_REG_RW("Context 0 IEC958 CS", 0),
+ SOC_SINGLE_REG_RW("Context 1 IEC958 CS", 1),
+ SOC_SINGLE_REG_RW("Context 2 IEC958 CS", 2),
+ SOC_SINGLE_REG_RW("Context 3 IEC958 CS", 3),
};

/*
--
2.34.1