lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAA+D8AMvZK_OLgf+ocxZDDBXi-L1VYwHi-EoTBcC0_gcxoLmHQ@mail.gmail.com>
Date: Fri, 28 Nov 2025 15:44:31 +0800
From: Shengjiu Wang <shengjiu.wang@...il.com>
To: Chancel Liu <chancel.liu@....com>
Cc: Xiubo.Lee@...il.com, festevam@...il.com, nicoleotsuka@...il.com, 
	lgirdwood@...il.com, broonie@...nel.org, perex@...ex.cz, tiwai@...e.com, 
	linuxppc-dev@...ts.ozlabs.org, linux-kernel@...r.kernel.org, 
	linux-sound@...r.kernel.org
Subject: Re: [PATCH v2 2/2] ASoC: fsl_micfil: Set channel range control

On Thu, Nov 27, 2025 at 10:27 AM Chancel Liu <chancel.liu@....com> wrote:
>
> The range control register can't directly adjust volume gain according
> to specification. It's the dynamic range of the CIC filter. The range
> value should meet some conditions otherwise the channel data is not
> reliable. Add an array in soc data to store const value in formula
> with which range with all quality on different platforms can be
> calculated. If the value set to range control exceeds the max range
> there'll be warning logs.
>
> Signed-off-by: Chancel Liu <chancel.liu@....com>

Acked-by: Shengjiu Wang <shengjiu.wang@...il.com>

Best regards
Shengjiu wang
> ---
>  sound/soc/fsl/fsl_micfil.c | 125 ++++++++++++++++++++++++++++++-------
>  1 file changed, 103 insertions(+), 22 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
> index 86678fee7a57..d6cde2757c6d 100644
> --- a/sound/soc/fsl/fsl_micfil.c
> +++ b/sound/soc/fsl/fsl_micfil.c
> @@ -17,6 +17,7 @@
>  #include <linux/sysfs.h>
>  #include <linux/types.h>
>  #include <linux/dma/imx-dma.h>
> +#include <linux/log2.h>
>  #include <sound/dmaengine_pcm.h>
>  #include <sound/pcm.h>
>  #include <sound/pcm_params.h>
> @@ -93,6 +94,8 @@ struct fsl_micfil_soc_data {
>         u64  formats;
>         int  fifo_offset;
>         enum quality default_quality;
> +       /* stores const value in formula to calculate range */
> +       int rangeadj_const[3][2];
>  };
>
>  static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
> @@ -115,6 +118,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
>         .volume_sx = false,
>         .fifo_offset = 0,
>         .default_quality = QUALITY_MEDIUM,
> +       .rangeadj_const = {{27, 7}, {27, 7}, {26, 7}},
>  };
>
>  static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
> @@ -128,6 +132,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
>         .volume_sx = false,
>         .fifo_offset = 0,
>         .default_quality = QUALITY_MEDIUM,
> +       .rangeadj_const = {{30, 6}, {30, 6}, {29, 6}},
>  };
>
>  static struct fsl_micfil_soc_data fsl_micfil_imx943 = {
> @@ -141,6 +146,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx943 = {
>         .volume_sx = false,
>         .fifo_offset = -4,
>         .default_quality = QUALITY_MEDIUM,
> +       .rangeadj_const = {{34, 6}, {34, 6}, {33, 6}},
>  };
>
>  static const struct of_device_id fsl_micfil_dt_ids[] = {
> @@ -167,9 +173,69 @@ static const struct soc_enum fsl_micfil_quality_enum =
>
>  static DECLARE_TLV_DB_SCALE(gain_tlv, 0, 100, 0);
>
> +static int micfil_get_max_range(struct fsl_micfil *micfil)
> +{
> +       int max_range;
> +
> +       switch (micfil->quality) {
> +       case QUALITY_HIGH:
> +       case QUALITY_VLOW0:
> +               max_range = micfil->soc->rangeadj_const[0][0] - micfil->soc->rangeadj_const[0][1] *
> +                           ilog2(2 * MICFIL_OSR_DEFAULT);
> +               break;
> +       case QUALITY_MEDIUM:
> +       case QUALITY_VLOW1:
> +               max_range = micfil->soc->rangeadj_const[1][0] - micfil->soc->rangeadj_const[1][1] *
> +                           ilog2(MICFIL_OSR_DEFAULT);
> +               break;
> +       case QUALITY_LOW:
> +       case QUALITY_VLOW2:
> +               max_range = micfil->soc->rangeadj_const[2][0] - micfil->soc->rangeadj_const[2][1] *
> +                           ilog2(MICFIL_OSR_DEFAULT);
> +               break;
> +       default:
> +               return 0;
> +       }
> +       max_range = max_range < 0 ? 0 : max_range;
> +
> +       return max_range;
> +}
> +
> +static int micfil_range_set(struct snd_kcontrol *kcontrol,
> +                           struct snd_ctl_elem_value *ucontrol)
> +{
> +       struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
> +       struct fsl_micfil *micfil = snd_soc_component_get_drvdata(cmpnt);
> +       struct soc_mixer_control *mc =
> +               (struct soc_mixer_control *)kcontrol->private_value;
> +       unsigned int shift = mc->shift;
> +       int max_range, new_range;
> +
> +       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);
> +
> +       return 0;
> +}
> +
>  static int micfil_set_quality(struct fsl_micfil *micfil)
>  {
> -       u32 qsel;
> +       int range, max_range;
> +       u32 qsel, val;
> +       int i;
> +
> +       if (!micfil->soc->volume_sx) {
> +               regmap_read(micfil->regmap, REG_MICFIL_OUT_CTRL, &val);
> +               max_range = micfil_get_max_range(micfil);
> +               for (i = 0; i < micfil->soc->fifos; i++) {
> +                       range = (val >> MICFIL_OUTGAIN_CHX_SHIFT(i)) & 0xF;
> +                       if (range > max_range)
> +                               dev_warn(&micfil->pdev->dev, "please reset channel %d range\n", i);
> +               }
> +       }
>
>         switch (micfil->quality) {
>         case QUALITY_HIGH:
> @@ -367,23 +433,31 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol,
>         return 0;
>  }
>
> -static const struct snd_kcontrol_new fsl_micfil_volume_controls[] = {
> -       SOC_SINGLE_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0, gain_tlv),
> -       SOC_SINGLE_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
> -                      MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0, gain_tlv),
> +static const struct snd_kcontrol_new fsl_micfil_range_controls[] = {
> +       SOC_SINGLE_EXT("CH0 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH1 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH2 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH3 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH4 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH5 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH6 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
> +       SOC_SINGLE_EXT("CH7 Range", REG_MICFIL_OUT_CTRL,
> +                      MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0,
> +                      snd_soc_get_volsw, micfil_range_set),
>  };
>
>  static const struct snd_kcontrol_new fsl_micfil_volume_sx_controls[] = {
> @@ -895,13 +969,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
>         struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
>         struct device *dev = cpu_dai->dev;
>         unsigned int val = 0;
> -       int ret, i;
> +       int ret, i, max_range;
>
>         micfil->quality = micfil->soc->default_quality;
>         micfil->card = cpu_dai->component->card;
>
>         /* set default gain to 2 */
> -       regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222);
> +       if (micfil->soc->volume_sx) {
> +               regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222);
> +       } else {
> +               max_range = micfil_get_max_range(micfil);
> +               for (i = 1; i < micfil->soc->fifos; i++)
> +                       max_range |= max_range << 4;
> +               regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, max_range);
> +       }
>
>         /* set DC Remover in bypass mode*/
>         for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++)
> @@ -935,8 +1016,8 @@ static int fsl_micfil_component_probe(struct snd_soc_component *component)
>                 snd_soc_add_component_controls(component, fsl_micfil_volume_sx_controls,
>                                                ARRAY_SIZE(fsl_micfil_volume_sx_controls));
>         else
> -               snd_soc_add_component_controls(component, fsl_micfil_volume_controls,
> -                                              ARRAY_SIZE(fsl_micfil_volume_controls));
> +               snd_soc_add_component_controls(component, fsl_micfil_range_controls,
> +                                              ARRAY_SIZE(fsl_micfil_range_controls));
>
>         return 0;
>  }
> --
> 2.50.1
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ