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

Shengjiu Wang posted 11 patches 2 days, 16 hours ago
There is a newer version of this series
[PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls
Posted by Shengjiu Wang 2 days, 16 hours ago
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
Re: [PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls
Posted by Mark Brown 2 days, 14 hours ago
On Mon, Mar 30, 2026 at 07:25:55PM +0800, Shengjiu Wang wrote:
> 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.

> @@ -100,22 +130,52 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,

> -	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;

This drops all the checking for changed values that we used to do so we
won't generate notifications to userspace.
Re: [PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls
Posted by Shengjiu Wang 2 days, 2 hours ago
On Mon, Mar 30, 2026 at 9:23 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Mon, Mar 30, 2026 at 07:25:55PM +0800, Shengjiu Wang wrote:
> > 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.
>
> > @@ -100,22 +130,52 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol,
>
> > -     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;
>
> This drops all the checking for changed values that we used to do so we
> won't generate notifications to userspace.

Yes,  as the type is changed to IEC958, the notification is not
acquired by the mixer-test.

Do we still need to add the notification?

best regards
Shengjiu Wang
Re: [PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls
Posted by Mark Brown 1 day, 15 hours ago
On Tue, Mar 31, 2026 at 09:58:22AM +0800, Shengjiu Wang wrote:
> On Mon, Mar 30, 2026 at 9:23 PM Mark Brown <broonie@kernel.org> wrote:

> > This drops all the checking for changed values that we used to do so we
> > won't generate notifications to userspace.

> Yes,  as the type is changed to IEC958, the notification is not
> acquired by the mixer-test.

> Do we still need to add the notification?

Yes, it should be there for all controls - it's just that mixer-test
doesn't have support for the IEC958 controls wired up so it's mostly
skipping them.  Someone should add that!  :P
Re: [PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls
Posted by Shengjiu Wang 1 day, 14 hours ago
On Tue, Mar 31, 2026 at 9:19 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Tue, Mar 31, 2026 at 09:58:22AM +0800, Shengjiu Wang wrote:
> > On Mon, Mar 30, 2026 at 9:23 PM Mark Brown <broonie@kernel.org> wrote:
>
> > > This drops all the checking for changed values that we used to do so we
> > > won't generate notifications to userspace.
>
> > Yes,  as the type is changed to IEC958, the notification is not
> > acquired by the mixer-test.
>
> > Do we still need to add the notification?
>
> Yes, it should be there for all controls - it's just that mixer-test
> doesn't have support for the IEC958 controls wired up so it's mostly
> skipping them.  Someone should add that!  :P

Thanks.  I will add the notification back in the next version.

Best regards
Shengjiu Wang