ASoC: fsl_micfil: Add a flag to distinguish with different volume control types
authorChancel Liu <chancel.liu@nxp.com>
Thu, 17 Oct 2024 07:15:07 +0000 (16:15 +0900)
committerMark Brown <broonie@kernel.org>
Fri, 18 Oct 2024 17:44:14 +0000 (18:44 +0100)
On i.MX8MM the register of volume control has positive and negative
values. It is different from other platforms like i.MX8MP and i.MX93
which only have positive values. Add a volume_sx flag to use SX_TLV
volume control for this kind of platform. Use common TLV volume control
for other platforms.

Fixes: cdfa92eb90f5 ("ASoC: fsl_micfil: Correct the number of steps on SX controls")
Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://patch.msgid.link/20241017071507.2577786-1-chancel.liu@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/fsl/fsl_micfil.c

index 193be098fa5e0ff524452ec2589edb1daf62559d..84638c1a2863ab9345d3a069fa49b17bc2bcd5af 100644 (file)
@@ -67,6 +67,7 @@ struct fsl_micfil_soc_data {
        bool imx;
        bool use_edma;
        bool use_verid;
+       bool volume_sx;
        u64  formats;
 };
 
@@ -76,6 +77,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mm = {
        .fifo_depth = 8,
        .dataline =  0xf,
        .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       .volume_sx = true,
 };
 
 static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
@@ -84,6 +86,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx8mp = {
        .fifo_depth = 32,
        .dataline =  0xf,
        .formats = SNDRV_PCM_FMTBIT_S32_LE,
+       .volume_sx = false,
 };
 
 static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
@@ -94,6 +97,7 @@ static struct fsl_micfil_soc_data fsl_micfil_imx93 = {
        .formats = SNDRV_PCM_FMTBIT_S32_LE,
        .use_edma = true,
        .use_verid = true,
+       .volume_sx = false,
 };
 
 static const struct of_device_id fsl_micfil_dt_ids[] = {
@@ -317,7 +321,26 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
+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_volume_sx_controls[] = {
        SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL,
                          MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv),
        SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL,
@@ -334,6 +357,9 @@ static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
                          MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv),
        SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL,
                          MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv),
+};
+
+static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = {
        SOC_ENUM_EXT("MICFIL Quality Select",
                     fsl_micfil_quality_enum,
                     micfil_quality_get, micfil_quality_set),
@@ -801,6 +827,20 @@ static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
        return 0;
 }
 
+static int fsl_micfil_component_probe(struct snd_soc_component *component)
+{
+       struct fsl_micfil *micfil = snd_soc_component_get_drvdata(component);
+
+       if (micfil->soc->volume_sx)
+               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));
+
+       return 0;
+}
+
 static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
        .probe          = fsl_micfil_dai_probe,
        .startup        = fsl_micfil_startup,
@@ -821,6 +861,7 @@ static struct snd_soc_dai_driver fsl_micfil_dai = {
 
 static const struct snd_soc_component_driver fsl_micfil_component = {
        .name           = "fsl-micfil-dai",
+       .probe          = fsl_micfil_component_probe,
        .controls       = fsl_micfil_snd_controls,
        .num_controls   = ARRAY_SIZE(fsl_micfil_snd_controls),
        .legacy_dai_naming      = 1,