From c7661bfc7422443df394c01e069ae4e5c3a7f04c Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:16 +0800 Subject: [PATCH 01/11] ASoC: fsl_micfil: Add access property for "VAD Detected" Add access property SNDRV_CTL_ELEM_ACCESS_READ for control "VAD Detected", which doesn't support put operation, otherwise there will be issue with mixer-test. Fixes: 29dbfeecab85 ("ASoC: fsl_micfil: Add Hardware Voice Activity Detector support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-2-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index d6cde2757c6d..79850211742c 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -503,7 +503,13 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { SOC_SINGLE("HWVAD ZCD Adjustment", REG_MICFIL_VAD0_ZCD, 8, 15, 0), SOC_SINGLE("HWVAD ZCD And Behavior Switch", REG_MICFIL_VAD0_ZCD, 4, 1, 0), - SOC_SINGLE_BOOL_EXT("VAD Detected", 0, hwvad_detected, NULL), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .name = "VAD Detected", + .info = snd_soc_info_bool_ext, + .get = hwvad_detected, + }, }; static int fsl_micfil_use_verid(struct device *dev) From 59b9061824f2179fe133e2636203548eaba3e528 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:17 +0800 Subject: [PATCH 02/11] ASoC: fsl_micfil: Fix event generation in hwvad_put_enable() ALSA controls should return 1 if the value in the control changed but the control put operation hwvad_put_enable() only returns 0 or a negative error code, causing ALSA to not generate any change events. Add a suitable check in the function before updating the vad_enabled variable. Fixes: 29dbfeecab85 ("ASoC: fsl_micfil: Add Hardware Voice Activity Detector support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-3-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 79850211742c..97f24c9bdd68 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -377,10 +377,15 @@ static int hwvad_put_enable(struct snd_kcontrol *kcontrol, unsigned int *item = ucontrol->value.enumerated.item; struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); int val = snd_soc_enum_item_to_val(e, item[0]); + bool change = false; + if (val < 0 || val > 1) + return -EINVAL; + + change = (micfil->vad_enabled != val); micfil->vad_enabled = val; - return 0; + return change; } static int hwvad_get_enable(struct snd_kcontrol *kcontrol, From 7e226209906906421f0d952d7304e48fdb0adabc Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:18 +0800 Subject: [PATCH 03/11] ASoC: fsl_micfil: Fix event generation in hwvad_put_init_mode() ALSA controls should return 1 if the value in the control changed but the control put operation hwvad_put_init_mode() only returns 0 or a negative error code, causing ALSA to not generate any change events. Add a suitable check in the function before updating the vad_init_mode variable. Fixes: 29dbfeecab85 ("ASoC: fsl_micfil: Add Hardware Voice Activity Detector support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-4-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 97f24c9bdd68..1c826e0cb1d5 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -407,13 +407,18 @@ static int hwvad_put_init_mode(struct snd_kcontrol *kcontrol, unsigned int *item = ucontrol->value.enumerated.item; struct fsl_micfil *micfil = snd_soc_component_get_drvdata(comp); int val = snd_soc_enum_item_to_val(e, item[0]); + bool change = false; + + if (val < MICFIL_HWVAD_ENVELOPE_MODE || val > MICFIL_HWVAD_ENERGY_MODE) + return -EINVAL; /* 0 - Envelope-based Mode * 1 - Energy-based Mode */ + change = (micfil->vad_init_mode != val); micfil->vad_init_mode = val; - return 0; + return change; } static int hwvad_get_init_mode(struct snd_kcontrol *kcontrol, From fc4daaddb276d370b7da3819872044df446a1911 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:19 +0800 Subject: [PATCH 04/11] ASoC: fsl_micfil: Fix event generation in micfil_range_set() ALSA controls should return 1 if the value in the control changed but the control put operation micfil_range_set() only returns 0 or a negative error code, causing ALSA to not generate any change events. Use snd_soc_component_update_bits() function to replace the regmap_update_bits(), for snd_soc_component_update_bits() has the capability of return check status. Also enable pm runtime before calling the function snd_soc_component_update_bits() to make the regmap cache data align with the value in hardware. Fixes: ef1a7e02fdb7 ("ASoC: fsl_micfil: Set channel range control") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-5-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 1c826e0cb1d5..0cfdd6343291 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -210,15 +210,23 @@ static int micfil_range_set(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int shift = mc->shift; int max_range, new_range; + int ret; new_range = ucontrol->value.integer.value[0]; max_range = micfil_get_max_range(micfil); if (new_range > max_range) dev_warn(&micfil->pdev->dev, "range makes channel %d data unreliable\n", shift / 4); - regmap_update_bits(micfil->regmap, REG_MICFIL_OUT_CTRL, 0xF << shift, new_range << shift); + ret = pm_runtime_resume_and_get(cmpnt->dev); + if (ret) + return ret; - return 0; + ret = snd_soc_component_update_bits(cmpnt, REG_MICFIL_OUT_CTRL, 0xF << shift, + new_range << shift); + + pm_runtime_put_autosuspend(cmpnt->dev); + + return ret; } static int micfil_set_quality(struct fsl_micfil *micfil) From 7d2bd35100de370dc326b250e8f6b66bee06a2f3 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:20 +0800 Subject: [PATCH 05/11] ASoC: fsl_micfil: Fix event generation in micfil_put_dc_remover_state() ALSA controls should return 1 if the value in the control changed but the control put operation micfil_put_dc_remover_state() only returns 0 or a negative error code, causing ALSA to not generate any change events. return the value of snd_soc_component_update_bits() directly, as it has the capability of return check status of changed or not. Also enable pm runtime before calling the function snd_soc_component_update_bits() to make the regmap cache data align with the value in hardware. Fixes: 29dbfeecab85 ("ASoC: fsl_micfil: Add Hardware Voice Activity Detector support") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-6-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 0cfdd6343291..983805bbaae2 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -351,6 +351,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol, if (val < 0 || val > 3) return -EINVAL; + ret = pm_runtime_resume_and_get(comp->dev); + if (ret) + return ret; + micfil->dc_remover = val; /* Calculate total value for all channels */ @@ -360,10 +364,10 @@ static int micfil_put_dc_remover_state(struct snd_kcontrol *kcontrol, /* Update DC Remover mode for all channels */ ret = snd_soc_component_update_bits(comp, REG_MICFIL_DC_CTRL, MICFIL_DC_CTRL_CONFIG, reg_val); - if (ret < 0) - return ret; - return 0; + pm_runtime_put_autosuspend(comp->dev); + + return ret; } static int micfil_get_dc_remover_state(struct snd_kcontrol *kcontrol, From e5785093b1b45af7ee57d18619b2854a8aed073a Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:21 +0800 Subject: [PATCH 06/11] ASoC: fsl_micfil: Fix event generation in micfil_quality_set() ALSA controls should return 1 if the value in the control changed but the control put operation micfil_quality_set() only returns 0 or a negative error code, causing ALSA to not generate any change events. Add a suitable check in the function before updating the quality variable. Also enable pm runtime before calling the function micfil_set_quality() to make the regmap cache data align with the value in hardware. Fixes: bea1d61d5892 ("ASoC: fsl_micfil: rework quality setting") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-7-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_micfil.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 983805bbaae2..2e887f1f1f36 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -289,10 +289,34 @@ static int micfil_quality_set(struct snd_kcontrol *kcontrol, { struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol); struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt); + int val = ucontrol->value.integer.value[0]; + bool change = false; + int old_val; + int ret; - micfil->quality = ucontrol->value.integer.value[0]; + if (val < QUALITY_HIGH || val > QUALITY_VLOW2) + return -EINVAL; - return micfil_set_quality(micfil); + if (micfil->quality != val) { + ret = pm_runtime_resume_and_get(cmpnt->dev); + if (ret) + return ret; + + old_val = micfil->quality; + micfil->quality = val; + ret = micfil_set_quality(micfil); + + pm_runtime_put_autosuspend(cmpnt->dev); + + if (ret) { + micfil->quality = old_val; + return ret; + } + + change = true; + } + + return change; } static const char * const micfil_hwvad_enable[] = { From 1b61c8103c9317a9c37fe544c2d83cee1c281149 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:22 +0800 Subject: [PATCH 07/11] ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_arc_mode_put() ALSA controls should return 1 if the value in the control changed but the control put operation fsl_xcvr_arc_mode_put() only returns 0 or a negative error code, causing ALSA to not generate any change events. Add a suitable check in the function before updating the arc_mode variable. Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-8-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_xcvr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index a268fb81a2f8..008e45009c83 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -115,10 +115,17 @@ static int fsl_xcvr_arc_mode_put(struct snd_kcontrol *kcontrol, struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; + int val = snd_soc_enum_item_to_val(e, item[0]); + int ret; - xcvr->arc_mode = snd_soc_enum_item_to_val(e, item[0]); + if (val < 0 || val > 1) + return -EINVAL; - return 0; + ret = (xcvr->arc_mode != val); + + xcvr->arc_mode = val; + + return ret; } static int fsl_xcvr_arc_mode_get(struct snd_kcontrol *kcontrol, From 64a496ba976324615b845d60739dfcdae3d57434 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:23 +0800 Subject: [PATCH 08/11] ASoC: fsl_xcvr: Fix event generation in fsl_xcvr_mode_put() ALSA controls should return 1 if the value in the control changed but the control put operation fsl_xcvr_mode_put() only returns 0 or a negative error code, causing ALSA to not generate any change events. Add a suitable check in the function before updating the mode variable. Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-9-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_xcvr.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 008e45009c83..d7a823384c08 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -225,10 +225,17 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, struct fsl_xcvr *xcvr = snd_soc_dai_get_drvdata(dai); struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int *item = ucontrol->value.enumerated.item; + int val = snd_soc_enum_item_to_val(e, item[0]); struct snd_soc_card *card = dai->component->card; struct snd_soc_pcm_runtime *rtd; + int ret; - xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); + if (val < FSL_XCVR_MODE_SPDIF || val > FSL_XCVR_MODE_EARC) + return -EINVAL; + + ret = (xcvr->mode != val); + + xcvr->mode = val; fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, (xcvr->mode == FSL_XCVR_MODE_ARC)); @@ -238,7 +245,7 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, rtd = snd_soc_get_pcm_runtime(card, card->dai_link); rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = (xcvr->mode == FSL_XCVR_MODE_SPDIF ? 1 : 0); - return 0; + return ret; } static int fsl_xcvr_mode_get(struct snd_kcontrol *kcontrol, From 00541b86fb578d4949cfdd6aff1f82d43fcf07af Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:24 +0800 Subject: [PATCH 09/11] ASoC: fsl_easrc: Check the variable range in fsl_easrc_iec958_put_bits() Add check of input value's range in fsl_easrc_iec958_put_bits(), otherwise the wrong value may be written from user space. Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-10-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 6c56134c60cc..6de1e1d3d8dc 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -54,6 +54,9 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, unsigned int regval = ucontrol->value.integer.value[0]; int ret; + if (regval < EASRC_WIDTH_16_BIT || regval > EASRC_WIDTH_24_BIT) + return -EINVAL; + ret = (easrc_priv->bps_iec958[mc->regbase] != regval); easrc_priv->bps_iec958[mc->regbase] = regval; From aa21fe4a81458cf469c2615b08cbde5997dde25a Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:25 +0800 Subject: [PATCH 10/11] ASoC: fsl_easrc: Fix value type in fsl_easrc_iec958_get_bits() The value type of controls "Context 0 IEC958 Bits Per Sample" should be integer, not enumerated, the issue is found by the mixer-test. Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers") Signed-off-by: Shengjiu Wang Link: https://patch.msgid.link/20260401094226.2900532-11-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index 6de1e1d3d8dc..fbd1ba12aad0 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -73,7 +73,7 @@ static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; - ucontrol->value.enumerated.item[0] = easrc_priv->bps_iec958[mc->regbase]; + ucontrol->value.integer.value[0] = easrc_priv->bps_iec958[mc->regbase]; return 0; } From 47f28a5bd154a95d5aa563dde02a801bd32ddb81 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Wed, 1 Apr 2026 17:42:26 +0800 Subject: [PATCH 11/11] ASoC: fsl_easrc: Change the type for iec958 channel status controls 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 Link: https://patch.msgid.link/20260401094226.2900532-12-shengjiu.wang@nxp.com Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_easrc.c | 118 +++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index fbd1ba12aad0..41985162df0b 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), ®val[0]); + if (ret) + return ret; - ucontrol->value.integer.value[0] = regval; + ret = regmap_read(easrc->regmap, REG_EASRC_CS1(mc->regbase), ®val[1]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS2(mc->regbase), ®val[2]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS3(mc->regbase), ®val[3]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS4(mc->regbase), ®val[4]); + if (ret) + return ret; + + ret = regmap_read(easrc->regmap, REG_EASRC_CS5(mc->regbase), ®val[5]); + if (ret) + return ret; return 0; } @@ -100,22 +130,62 @@ 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; + bool changed, changed_all = false; 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_check(easrc->regmap, REG_EASRC_CS0(mc->regbase), + GENMASK(31, 0), regval[0], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS1(mc->regbase), + GENMASK(31, 0), regval[1], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS2(mc->regbase), + GENMASK(31, 0), regval[2], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS3(mc->regbase), + GENMASK(31, 0), regval[3], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS4(mc->regbase), + GENMASK(31, 0), regval[4], &changed); + if (ret != 0) + goto err; + changed_all |= changed; + + ret = regmap_update_bits_check(easrc->regmap, REG_EASRC_CS5(mc->regbase), + GENMASK(31, 0), regval[5], &changed); + if (ret != 0) + goto err; + changed_all |= changed; +err: + pm_runtime_put_autosuspend(component->dev); + + if (ret != 0) + return ret; + else + return changed_all; } #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 +216,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), }; /*