mbox series

[v2,00/17] ASoC: mediatek: Add support for MT8186 SoC

Message ID 20220217134205.15400-1-jiaxin.yu@mediatek.com
Headers show
Series ASoC: mediatek: Add support for MT8186 SoC | expand

Message

Jiaxin Yu (俞家鑫) Feb. 17, 2022, 1:41 p.m. UTC
This series of patches adds support for Mediatek AFE of MT8186 Soc.
Patches are based on broonie tree "for-next" branch.

Changes since v1:
  [v2 01/17]
    - add a new ID to the existing mt6358 codec driver
  [v2 03/17]
    - modify log level in DAPM events
    - use standard numeric control with name ending in Switch
    - return 1 when the value changed in mixer control's .get callback
  [v2 05/17]
    - ending in Switch to the standard on/off controls
    - change to "HW Gain 1 Volume" and "HW Gain 2 Volume"
  [v2 09/17]
    - return an error in the default case rather than just picking one of
      the behaviours when do .set_fmt
    - use the new defines that are _PROVIDER_MASK, _DAIFMT_CBP_CFP and
      _DAIFMT_CBC_CFC
  [v2 10/17]
  [v2 11/17]
    - the clock and gpio are aplit out into separate  patches

  The source file's GPL comment use c++ style, and the header fils's GPL
  comment use c style. We have added "Switch" after the names of all the
  controls that just are simple on/off.

Jiaxin Yu (17):
  ASoC: mediatek: mt6366: add codec driver
  ASoC: mediatek: mt8186: support audsys clock control
  ASoC: mediatek: mt8186: support adda in platform driver
  ASoC: mediatek: mt8186: support hostless in platform driver
  ASoC: mediatek: mt8186: support hw gain in platform driver
  ASoC: mediatek: mt8186: support i2s in platform driver
  ASoC: mediatek: mt8186: support pcm in platform driver
  ASoC: mediatek: mt8186: support src in platform driver
  ASoC: mediatek: mt8186: support tdm in platform driver
  ASoC: mediatek: mt8186: support audio clock control in platform driver
  ASoC: mediatek: mt8186: support gpio control in platform driver
  ASoC: mediatek: mt8186: add platform driver
  dt-bindings: mediatek: mt8186: add audio afe document
  ASoC: mediatek: mt8186: add machine driver with mt6366, da7219 and
    max98357
  dt-bindings: mediatek: mt8186: add mt8186-mt6366-da7219-max98357
    document
  ASoC: mediatek: mt8186: add machine driver with mt6366, rt1019 and
    rt5682s
  dt-bindings: mediatek: mt8186: add mt8186-mt6366-rt1019-rt5682s
    document

 .../bindings/sound/mt8186-afe-pcm.yaml        |  175 +
 .../sound/mt8186-mt6366-da7219-max98357.yaml  |   47 +
 .../sound/mt8186-mt6366-rt1019-rt5682s.yaml   |   47 +
 sound/soc/codecs/Kconfig                      |    8 +
 sound/soc/codecs/Makefile                     |    1 +
 sound/soc/mediatek/Kconfig                    |   44 +
 sound/soc/mediatek/Makefile                   |    1 +
 sound/soc/mediatek/mt8186/Makefile            |   21 +
 sound/soc/mediatek/mt8186/mt8186-afe-clk.c    |  719 ++++
 sound/soc/mediatek/mt8186/mt8186-afe-clk.h    |  210 +
 sound/soc/mediatek/mt8186/mt8186-afe-common.h |  245 ++
 .../soc/mediatek/mt8186/mt8186-afe-control.c  |  261 ++
 sound/soc/mediatek/mt8186/mt8186-afe-gpio.c   |  210 +
 sound/soc/mediatek/mt8186/mt8186-afe-gpio.h   |   19 +
 sound/soc/mediatek/mt8186/mt8186-afe-pcm.c    | 3029 +++++++++++++++
 sound/soc/mediatek/mt8186/mt8186-audsys-clk.c |  150 +
 sound/soc/mediatek/mt8186/mt8186-audsys-clk.h |   15 +
 .../soc/mediatek/mt8186/mt8186-audsys-clkid.h |   45 +
 sound/soc/mediatek/mt8186/mt8186-dai-adda.c   |  891 +++++
 .../soc/mediatek/mt8186/mt8186-dai-hostless.c |  295 ++
 .../soc/mediatek/mt8186/mt8186-dai-hw-gain.c  |  245 ++
 sound/soc/mediatek/mt8186/mt8186-dai-i2s.c    | 1371 +++++++
 sound/soc/mediatek/mt8186/mt8186-dai-pcm.c    |  432 +++
 sound/soc/mediatek/mt8186/mt8186-dai-src.c    |  758 ++++
 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c    |  713 ++++
 .../mediatek/mt8186/mt8186-interconnection.h  |   69 +
 .../soc/mediatek/mt8186/mt8186-misc-control.c | 1728 +++++++++
 .../mt8186/mt8186-mt6366-da7219-max98357.c    |  910 +++++
 .../mt8186/mt8186-mt6366-rt1019-rt5682s.c     |  894 +++++
 sound/soc/mediatek/mt8186/mt8186-reg.h        | 3433 +++++++++++++++++
 30 files changed, 16986 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/mt8186-afe-pcm.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8186-mt6366-da7219-max98357.yaml
 create mode 100644 Documentation/devicetree/bindings/sound/mt8186-mt6366-rt1019-rt5682s.yaml
 create mode 100644 sound/soc/mediatek/mt8186/Makefile
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-common.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-control.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clk.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clk.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-audsys-clkid.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-adda.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hostless.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-src.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-interconnection.h
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-misc-control.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c
 create mode 100644 sound/soc/mediatek/mt8186/mt8186-reg.h

Comments

AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #1
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> Mt6366 is a new version of mt6358, and they are same about audio part.
> So we can reuse the driver of mt6358.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>

Hello Jiaxin,
I'm sorry but this commit makes very little sense.

If you want to advertise MT6366 support, please write a note and/or
a new compatible string inside of the mt6358 driver (and dt-bindings),
then, please drop this commit.


> ---
>   sound/soc/codecs/Kconfig  | 8 ++++++++
>   sound/soc/codecs/Makefile | 1 +
>   2 files changed, 9 insertions(+)
> 
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> index 8fa24783ce01..6631094678f5 100644
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -132,6 +132,7 @@ config SND_SOC_ALL_CODECS
>   	imply SND_SOC_MT6351
>   	imply SND_SOC_MT6358
>   	imply SND_SOC_MT6359
> +	imply SND_SOC_MT6366
>   	imply SND_SOC_MT6660
>   	imply SND_SOC_NAU8315
>   	imply SND_SOC_NAU8540
> @@ -1888,6 +1889,13 @@ config SND_SOC_MT6359_ACCDET
>   	  for ASoC codec soc-jack detection mechanism.
>   	  Select N if you don't have jack on board.
>   
> +config SND_SOC_MT6366
> +	tristate "MediaTek MT6366 Codec"
> +	depends on MTK_PMIC_WRAP
> +	help
> +	  Enable support for the platform which uses MT6366 as
> +	  external codec device.
> +
>   config SND_SOC_MT6660
>   	tristate "Mediatek MT6660 Speaker Amplifier"
>   	depends on I2C
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> index 42d00aa4ee46..1279684feaf0 100644
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -465,6 +465,7 @@ obj-$(CONFIG_SND_SOC_MT6351)	+= snd-soc-mt6351.o
>   obj-$(CONFIG_SND_SOC_MT6358)	+= snd-soc-mt6358.o
>   obj-$(CONFIG_SND_SOC_MT6359)	+= snd-soc-mt6359.o
>   obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o
> +obj-$(CONFIG_SND_SOC_MT6366)	+= snd-soc-mt6358.o
>   obj-$(CONFIG_SND_SOC_MT6660)	+= snd-soc-mt6660.o
>   obj-$(CONFIG_SND_SOC_NAU8315)   += snd-soc-nau8315.o
>   obj-$(CONFIG_SND_SOC_NAU8540)   += snd-soc-nau8540.o
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #2
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 hostless dai driver.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   .../soc/mediatek/mt8186/mt8186-dai-hostless.c | 295 ++++++++++++++++++
>   1 file changed, 295 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hostless.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c b/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c
> new file mode 100644
> index 000000000000..37460a3acc93
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-hostless.c
> @@ -0,0 +1,295 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI Hostless Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include "mt8186-afe-common.h"
> +
> +static const struct snd_pcm_hardware mt8186_hostless_hardware = {
> +	.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
> +		 SNDRV_PCM_INFO_MMAP_VALID),
> +	.period_bytes_min = 256,
> +	.period_bytes_max = 4 * 48 * 1024,
> +	.periods_min = 2,
> +	.periods_max = 256,
> +	.buffer_bytes_max = 4 * 48 * 1024,
> +	.fifo_size = 0,
> +};
> +
> +/* dai component */
> +static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = {
> +	/* Hostless ADDA Loopback */
> +	{"ADDA_DL_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
> +	{"ADDA_DL_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
> +	{"ADDA_DL_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
> +	{"ADDA_DL_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
> +	{"I2S1_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
> +	{"I2S1_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
> +	{"I2S3_CH1", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
> +	{"I2S3_CH1", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
> +	{"I2S3_CH2", "ADDA_UL_CH1 Switch", "Hostless LPBK DL"},
> +	{"I2S3_CH2", "ADDA_UL_CH2 Switch", "Hostless LPBK DL"},
> +	{"Hostless LPBK UL", NULL, "ADDA_UL_Mux"},
> +
> +	/* Hostelss FM */
> +	/* connsys_i2s to hw gain 1*/
> +	{"Hostless FM UL", NULL, "Connsys I2S"},
> +
> +	{"HW_GAIN1_IN_CH1", "CONNSYS_I2S_CH1 Switch", "Hostless FM DL"},
> +	{"HW_GAIN1_IN_CH2", "CONNSYS_I2S_CH2 Switch", "Hostless FM DL"},
> +	/* hw gain to adda dl */
> +	{"Hostless FM UL", NULL, "HW Gain 1 Out"},
> +
> +	{"ADDA_DL_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
> +	{"ADDA_DL_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
> +	/* hw gain to i2s3 */
> +	{"I2S3_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
> +	{"I2S3_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
> +	/* hw gain to i2s1 */
> +	{"I2S1_CH1", "GAIN1_OUT_CH1 Switch", "Hostless FM DL"},
> +	{"I2S1_CH2", "GAIN1_OUT_CH2 Switch", "Hostless FM DL"},
> +
> +	/* Hostless_SRC */
> +	{"ADDA_DL_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
> +	{"ADDA_DL_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
> +	{"I2S1_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
> +	{"I2S1_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
> +	{"I2S3_CH1", "SRC_1_OUT_CH1 Switch", "Hostless_SRC_1_DL"},
> +	{"I2S3_CH2", "SRC_1_OUT_CH2 Switch", "Hostless_SRC_1_DL"},
> +	{"Hostless_SRC_1_UL", NULL, "HW_SRC_1_Out"},
> +
> +	/* Hostless_SRC_bargein */
> +	{"HW_SRC_1_IN_CH1", "I2S0_CH1 Switch", "Hostless_SRC_Bargein_DL"},
> +	{"HW_SRC_1_IN_CH2", "I2S0_CH2 Switch", "Hostless_SRC_Bargein_DL"},
> +	{"Hostless_SRC_Bargein_UL", NULL, "I2S0"},
> +
> +	/* Hostless AAudio */
> +	{"Hostless HW Gain AAudio In", NULL, "HW Gain 2 In"},
> +	{"Hostless SRC AAudio UL", NULL, "HW Gain 2 Out"},
> +	{"HW_SRC_2_IN_CH1", "HW_GAIN2_OUT_CH1 Switch", "Hostless SRC AAudio DL"},
> +	{"HW_SRC_2_IN_CH2", "HW_GAIN2_OUT_CH2 Switch", "Hostless SRC AAudio DL"},
> +};
> +
> +/* dai ops */
> +static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,
> +				    struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	int ret;
> +
> +	snd_soc_set_runtime_hwparams(substream, &mt8186_hostless_hardware);
> +
> +	ret = snd_pcm_hw_constraint_integer(runtime,
> +					    SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		dev_info(afe->dev, "snd_pcm_hw_constraint_integer failed\n");

	if (ret < 0) {
		dev_err(afe->dev, "setting constraints failed: %d\n", ret);
		return ret;
	}

	return 0;


Thanks,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #3
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 adda dai driver
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 891 ++++++++++++++++++++
>   1 file changed, 891 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> new file mode 100644
> index 000000000000..6d7dd1533da0
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> @@ -0,0 +1,891 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI ADDA Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/regmap.h>
> +#include <linux/delay.h>
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-gpio.h"
> +#include "mt8186-interconnection.h"
> +

..snip..


> +
> +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
> +				     struct snd_kcontrol *kcontrol,
> +				     int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int delay_data;
> +	int delay_cycle;
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2_CLK_P2) {
> +			/* set protocol 2 */
> +			regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
> +				     0x00010000);

No leading zeros, please (also, it fits in one line):
			regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x10000);

> +			/* mtkaif_rxif_clkinv_adc inverse */
> +			regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
> +					   MTKAIF_RXIF_CLKINV_ADC_MASK_SFT,
> +					   0x1 << MTKAIF_RXIF_CLKINV_ADC_SFT);

Please use the BIT() macro:
					   BIT(MTKAIF_RXIF_CLKINV_ADC_SFT)

> +
> +			if (strcmp(w->name, "ADDA_MTKAIF_CFG") == 0) {
> +				if (afe_priv->mtkaif_chosen_phase[0] < 0 &&
> +				    afe_priv->mtkaif_chosen_phase[1] < 0) {
> +					dev_err(afe->dev,
> +						"%s(), calib fail mtkaif_chosen_phase[0/1]:%d/%d\n",
> +						__func__,
> +						afe_priv->mtkaif_chosen_phase[0],
> +						afe_priv->mtkaif_chosen_phase[1]);
> +					break;
> +				}
> +
> +				if (afe_priv->mtkaif_chosen_phase[0] < 0 ||
> +				    afe_priv->mtkaif_chosen_phase[1] < 0) {
> +					dev_err(afe->dev,
> +						"%s(), skip dealy setting mtkaif_chosen_phase[0/1]:%d/%d\n",
> +						__func__,
> +						afe_priv->mtkaif_chosen_phase[0],
> +						afe_priv->mtkaif_chosen_phase[1]);
> +					break;
> +				}
> +			}
> +
> +			/* set delay for ch12 */
> +			if (afe_priv->mtkaif_phase_cycle[0] >=
> +			    afe_priv->mtkaif_phase_cycle[1]) {
> +				delay_data = DELAY_DATA_MISO1;
> +				delay_cycle = afe_priv->mtkaif_phase_cycle[0] -
> +					      afe_priv->mtkaif_phase_cycle[1];
> +			} else {
> +				delay_data = DELAY_DATA_MISO2;
> +				delay_cycle = afe_priv->mtkaif_phase_cycle[1] -
> +					      afe_priv->mtkaif_phase_cycle[0];
> +			}
> +
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_MTKAIF_RX_CFG2,
> +					   MTKAIF_RXIF_DELAY_DATA_MASK_SFT,
> +					   delay_data <<
> +					   MTKAIF_RXIF_DELAY_DATA_SFT);
> +
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_MTKAIF_RX_CFG2,
> +					   MTKAIF_RXIF_DELAY_CYCLE_MASK_SFT,
> +					   delay_cycle <<
> +					   MTKAIF_RXIF_DELAY_CYCLE_SFT);
> +
> +		} else if (afe_priv->mtkaif_protocol == MTKAIF_PROTOCOL_2) {
> +			regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
> +				     0x00010000);

No leading zeroes, please.

> +		} else {
> +			regmap_write(afe->regmap, AFE_ADDA_MTKAIF_CFG0, 0x0);

0x0 -> 0

> +		}
> +
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
> +			     struct snd_kcontrol *kcontrol,
> +			     int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +
> +	dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		mt8186_afe_gpio_request(afe->dev, true, MT8186_DAI_ADDA, 0);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		/* should delayed 1/fs(smallest is 8k) = 125us before afe off */
> +		usleep_range(125, 135);
> +		mt8186_afe_gpio_request(afe->dev, false, MT8186_DAI_ADDA, 0);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mt8186_adda_dmic_get(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	ucontrol->value.integer.value[0] = afe_priv->mtkaif_dmic;
> +
> +	return 0;
> +}
> +
> +static int mt8186_adda_dmic_set(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int dmic_on;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	dmic_on = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
> +		 __func__, kcontrol->id.name, dmic_on);

Shouldn't this be a dev_dbg() instead?

> +
> +	if (afe_priv->mtkaif_dmic == dmic_on)
> +		return 0;
> +
> +	afe_priv->mtkaif_dmic = dmic_on;
> +
> +	return 1;
> +}
> +

...snip...

> +
> +#define HIRES_THRESHOLD 48000
> +static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source,
> +				     struct snd_soc_dapm_widget *sink)
> +{
> +	struct snd_soc_dapm_widget *w = source;
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_adda_priv *adda_priv;
> +
> +	adda_priv = get_adda_priv_by_name(afe, w->name);
> +
> +	if (!adda_priv) {
> +		dev_info(afe->dev, "%s(), adda_priv == NULL", __func__);

dev_err()

> +		return 0;
> +	}
> +
> +	return (adda_priv->dl_rate > HIRES_THRESHOLD) ? 1 : 0;
> +}
> +
> +static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
> +				     struct snd_soc_dapm_widget *sink)
> +{
> +	struct snd_soc_dapm_widget *w = source;
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_adda_priv *adda_priv;
> +
> +	adda_priv = get_adda_priv_by_name(afe, w->name);
> +
> +	if (!adda_priv) {
> +		dev_info(afe->dev, "%s(), adda_priv == NULL", __func__);

dev_err()

> +		return 0;
> +	}
> +
> +	return (adda_priv->ul_rate > HIRES_THRESHOLD) ? 1 : 0;
> +}
> +

..snip..

> +};
> +
> +/* dai ops */
> +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
> +				  struct snd_pcm_hw_params *params,
> +				  struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	unsigned int rate = params_rate(params);
> +	int id = dai->id;
> +	struct mtk_afe_adda_priv *adda_priv = afe_priv->dai_priv[id];
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> +		 __func__,
> +		 id,
> +		 substream->stream,
> +		 rate);
> +
> +	if (!adda_priv) {
> +		dev_info(afe->dev, "%s(), adda_priv == NULL", __func__);
> +		return -EINVAL;
> +	}
> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +		unsigned int dl_src2_con0 = 0;
> +		unsigned int dl_src2_con1 = 0;

This initialization is redundant: you're never using these variables
before initializing them later, so initializing them to zero is not
needed here.

> +
> +		adda_priv->dl_rate = rate;
> +
> +		/* set sampling rate */
> +		dl_src2_con0 = adda_dl_rate_transform(afe, rate) <<
> +			       DL_2_INPUT_MODE_CTL_SFT;
> +
> +		/* set output mode, UP_SAMPLING_RATE_X8 */
> +		dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT);
> +
> +		/* turn off mute function */
> +		dl_src2_con0 |= (0x01 << DL_2_MUTE_CH2_OFF_CTL_PRE_SFT);

BIT() macro, please

> +		dl_src2_con0 |= (0x01 << DL_2_MUTE_CH1_OFF_CTL_PRE_SFT);
> +
> +		/* set voice input data if input sample rate is 8k or 16k */
> +		if (rate == 8000 || rate == 16000)
> +			dl_src2_con0 |= 0x01 << DL_2_VOICE_MODE_CTL_PRE_SFT;
> +
> +		/* SA suggest apply -0.3db to audio/speech path */
> +		dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL <<
> +			       DL_2_GAIN_CTL_PRE_SFT;
> +
> +		/* turn on down-link gain */
> +		dl_src2_con0 |= (0x01 << DL_2_GAIN_ON_CTL_PRE_SFT);
> +
> +		if (id == MT8186_DAI_ADDA) {
> +			/* clean predistortion */
> +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0, 0);
> +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1, 0);
> +
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_DL_SRC2_CON0, dl_src2_con0);
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_DL_SRC2_CON1, dl_src2_con1);
> +
> +			/* set sdm gain */
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
> +					   ATTGAIN_CTL_MASK_SFT,
> +					   AUDIO_SDM_LEVEL_NORMAL <<
> +					   ATTGAIN_CTL_SFT);
> +
> +			/* Use new 2nd sdm */
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_DL_SDM_DITHER_CON,
> +					   AFE_DL_SDM_DITHER_64TAP_EN_MASK_SFT,
> +					   0x1 << AFE_DL_SDM_DITHER_64TAP_EN_SFT);

BIT(AFE_DL_SDM_DITHER_64TAP_EN_SFT)

> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_DL_SDM_AUTO_RESET_CON,
> +					   AFE_DL_USE_NEW_2ND_SDM_MASK_SFT,
> +					   0x1 << AFE_DL_USE_NEW_2ND_SDM_SFT);

BIT(AFE_DL_USE_NEW_2ND_SDM_SFT)

> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
> +					   USE_3RD_SDM_MASK_SFT,
> +					   AUDIO_SDM_2ND << USE_3RD_SDM_SFT);
> +
> +			/* sdm auto reset */
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_DL_SDM_AUTO_RESET_CON,
> +				     SDM_AUTO_RESET_THRESHOLD);
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_DL_SDM_AUTO_RESET_CON,
> +					   SDM_AUTO_RESET_TEST_ON_MASK_SFT,
> +					   0x1 << SDM_AUTO_RESET_TEST_ON_SFT);

BIT(SDM_AUTO_RESET_TEST_ON_SFT)

> +		}
> +	} else {
> +		unsigned int voice_mode = 0;

what about...
		unsigned int ul_src_con0 = 0; /* default value */
		unsigned int voice_mode =  adda_ul_rate_transform(afe, rate);

> +		unsigned int ul_src_con0 = 0;	/* default value */
> +
> +		adda_priv->ul_rate = rate;
> +
> +		voice_mode = adda_ul_rate_transform(afe, rate);
> +
> +		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
> +
> +		/* enable iir */
> +		ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) &
> +			       UL_IIR_ON_TMP_CTL_MASK_SFT;
> +		ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) &
> +			       UL_IIRMODE_CTL_MASK_SFT;
> +		switch (id) {
> +		case MT8186_DAI_ADDA:
> +		case MT8186_DAI_AP_DMIC:
> +			/* 35Hz @ 48k */
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_IIR_COEF_02_01, 0x00000000);

Please drop leading zeroes:

regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_02_01, 0);

> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_IIR_COEF_04_03, 0x00003FB8);

... and also please write hex in lower-case:

regmap_write(afe->regmap,
	     AFE_ADDA_IIR_COEF_04_03, 0x03fb8);

> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_IIR_COEF_06_05, 0x3FB80000);
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_IIR_COEF_08_07, 0x3FB80000);
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_IIR_COEF_10_09, 0x0000C048);
> +
> +			regmap_write(afe->regmap,
> +				     AFE_ADDA_UL_SRC_CON0, ul_src_con0);
> +
> +			/* Using Internal ADC */
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_TOP_CON0,
> +					   0x1 << 0,
> +					   0x0 << 0);

Please use the BIT() macro:

regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, BIT(0), 0);

P.S.: 87 columns is ok

> +
> +			/* mtkaif_rxif_data_mode = 0, amic */
> +			regmap_update_bits(afe->regmap,
> +					   AFE_ADDA_MTKAIF_RX_CFG0,
> +					   0x1 << 0,
> +					   0x0 << 0);

same here.

> +			break;
> +		default:
> +			break;
> +		}
> +
> +		/* ap dmic */
> +		switch (id) {
> +		case MT8186_DAI_AP_DMIC:
> +			mtk_adda_ul_src_dmic(afe, id);
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	return 0;
> +}
> +

Regards,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #4
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This path adds mt8186 hw gain dai driver.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   .../soc/mediatek/mt8186/mt8186-dai-hw-gain.c  | 245 ++++++++++++++++++
>   1 file changed, 245 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c b/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c
> new file mode 100644
> index 000000000000..796878989727
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-hw-gain.c
> @@ -0,0 +1,245 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI HW Gain Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/regmap.h>
> +#include "mt8186-afe-common.h"
> +#include "mt8186-interconnection.h"
> +
> +#define HW_GAIN_1_EN_W_NAME "HW GAIN 1 Enable"
> +#define HW_GAIN_2_EN_W_NAME "HW GAIN 2 Enable"
> +
> +/* dai component */
> +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch1_mix[] = {
> +	SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH1 Switch", AFE_CONN13_1,
> +				    I_CONNSYS_I2S_CH1, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new mtk_hw_gain1_in_ch2_mix[] = {
> +	SOC_DAPM_SINGLE_AUTODISABLE("CONNSYS_I2S_CH2 Switch", AFE_CONN14_1,
> +				    I_CONNSYS_I2S_CH2, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new mtk_hw_gain2_in_ch1_mix[] = {
> +	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN15,
> +				    I_ADDA_UL_CH1, 1, 0),
> +};
> +
> +static const struct snd_kcontrol_new mtk_hw_gain2_in_ch2_mix[] = {
> +	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN16,
> +				    I_ADDA_UL_CH2, 1, 0),
> +};
> +
> +static int mtk_hw_gain_event(struct snd_soc_dapm_widget *w,
> +			     struct snd_kcontrol *kcontrol,
> +			     int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	unsigned int gain_cur;
> +	unsigned int gain_con1;
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		if (strcmp(w->name, HW_GAIN_1_EN_W_NAME) == 0) {
> +			gain_cur = AFE_GAIN1_CUR;
> +			gain_con1 = AFE_GAIN1_CON1;
> +		} else {
> +			gain_cur = AFE_GAIN2_CUR;
> +			gain_con1 = AFE_GAIN2_CON1;
> +		}
> +
> +		/* let hw gain ramp up, set cur gain to 0 */
> +		regmap_update_bits(afe->regmap,
> +				   gain_cur,
> +				   AFE_GAIN1_CUR_MASK_SFT,
> +				   0);

This fits in one line (86 columns is ok)

> +
> +		/* set target gain to 0 */
> +		regmap_update_bits(afe->regmap,
> +				   gain_con1,
> +				   GAIN1_TARGET_MASK_SFT,
> +				   0);

Same here.

> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct snd_soc_dapm_widget mtk_dai_hw_gain_widgets[] = {
> +	/* inter-connections */
> +	SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH1", SND_SOC_NOPM, 0, 0,
> +			   mtk_hw_gain1_in_ch1_mix,
> +			   ARRAY_SIZE(mtk_hw_gain1_in_ch1_mix)),
> +	SND_SOC_DAPM_MIXER("HW_GAIN1_IN_CH2", SND_SOC_NOPM, 0, 0,
> +			   mtk_hw_gain1_in_ch2_mix,
> +			   ARRAY_SIZE(mtk_hw_gain1_in_ch2_mix)),
> +	SND_SOC_DAPM_MIXER("HW_GAIN2_IN_CH1", SND_SOC_NOPM, 0, 0,
> +			   mtk_hw_gain2_in_ch1_mix,
> +			   ARRAY_SIZE(mtk_hw_gain2_in_ch1_mix)),
> +	SND_SOC_DAPM_MIXER("HW_GAIN2_IN_CH2", SND_SOC_NOPM, 0, 0,
> +			   mtk_hw_gain2_in_ch2_mix,
> +			   ARRAY_SIZE(mtk_hw_gain2_in_ch2_mix)),
> +
> +	SND_SOC_DAPM_SUPPLY(HW_GAIN_1_EN_W_NAME,
> +			    AFE_GAIN1_CON0, GAIN1_ON_SFT, 0,
> +			    mtk_hw_gain_event,
> +			    SND_SOC_DAPM_PRE_PMU),
> +
> +	SND_SOC_DAPM_SUPPLY(HW_GAIN_2_EN_W_NAME,
> +			    AFE_GAIN2_CON0, GAIN2_ON_SFT, 0,
> +			    mtk_hw_gain_event,
> +			    SND_SOC_DAPM_PRE_PMU),
> +
> +	SND_SOC_DAPM_INPUT("HW Gain 1 Out Endpoint"),
> +	SND_SOC_DAPM_INPUT("HW Gain 2 Out Endpoint"),
> +	SND_SOC_DAPM_OUTPUT("HW Gain 1 In Endpoint"),
> +};
> +
> +static const struct snd_soc_dapm_route mtk_dai_hw_gain_routes[] = {
> +	{"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH1"},
> +	{"HW Gain 1 In", NULL, "HW_GAIN1_IN_CH2"},
> +	{"HW Gain 2 In", NULL, "HW_GAIN2_IN_CH1"},
> +	{"HW Gain 2 In", NULL, "HW_GAIN2_IN_CH2"},
> +
> +	{"HW Gain 1 In", NULL, HW_GAIN_1_EN_W_NAME},
> +	{"HW Gain 1 Out", NULL, HW_GAIN_1_EN_W_NAME},
> +	{"HW Gain 2 In", NULL, HW_GAIN_2_EN_W_NAME},
> +	{"HW Gain 2 Out", NULL, HW_GAIN_2_EN_W_NAME},
> +
> +	{"HW Gain 1 In Endpoint", NULL, "HW Gain 1 In"},
> +	{"HW Gain 1 Out", NULL, "HW Gain 1 Out Endpoint"},
> +	{"HW Gain 2 Out", NULL, "HW Gain 2 Out Endpoint"},
> +};
> +
> +static const struct snd_kcontrol_new mtk_hw_gain_controls[] = {
> +	SOC_SINGLE("HW Gain 1 Volume", AFE_GAIN1_CON1,
> +		   GAIN1_TARGET_SFT, GAIN1_TARGET_MASK, 0),
> +	SOC_SINGLE("HW Gain 2 Volume", AFE_GAIN2_CON1,
> +		   GAIN2_TARGET_SFT, GAIN2_TARGET_MASK, 0),
> +};
> +
> +/* dai ops */
> +static int mtk_dai_gain_hw_params(struct snd_pcm_substream *substream,
> +				  struct snd_pcm_hw_params *params,
> +				  struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	unsigned int rate = params_rate(params);
> +	unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, dai->id);
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> +		 __func__,
> +		 dai->id,
> +		 substream->stream,
> +		 rate);

This should be:
	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",

		 __func__, dai->id, substream->stream, rate);
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #5
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 pcm dai driver.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-dai-pcm.c | 432 +++++++++++++++++++++
>   1 file changed, 432 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> new file mode 100644
> index 000000000000..73b3f720ed35
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> @@ -0,0 +1,432 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI I2S Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/regmap.h>
> +#include <sound/pcm_params.h>
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-gpio.h"
> +#include "mt8186-interconnection.h"
> +
> +struct mtk_afe_pcm_priv {
> +	unsigned int id;
> +	unsigned int fmt;
> +	unsigned int bck_invert;
> +	unsigned int lck_invert;
> +};
> +
> +enum AUD_TX_LCH_RPT {

lowercase enumeration names please...

enum aud_tx_lch_rpt {
	AUD_TX....BLAH
};

> +	AUD_TX_LCH_RPT_NO_REPEAT = 0,
> +	AUD_TX_LCH_RPT_REPEAT = 1
> +};
> +
> +enum AUD_VBT_16K_MODE {
> +	AUD_VBT_16K_MODE_DISABLE = 0,
> +	AUD_VBT_16K_MODE_ENABLE = 1
> +};
> +
> +enum AUD_EXT_MODEM {
> +	AUD_EXT_MODEM_SELECT_INTERNAL = 0,
> +	AUD_EXT_MODEM_SELECT_EXTERNAL = 1
> +};
> +
> +enum AUD_PCM_SYNC_TYPE {
> +	/* bck sync length = 1 */
> +	AUD_PCM_ONE_BCK_CYCLE_SYNC = 0,
> +	/* bck sync length = PCM_INTF_CON1[9:13] */
> +	AUD_PCM_EXTENDED_BCK_CYCLE_SYNC = 1
> +};
> +
> +enum AUD_BT_MODE {
> +	AUD_BT_MODE_DUAL_MIC_ON_TX = 0,
> +	AUD_BT_MODE_SINGLE_MIC_ON_TX = 1
> +};
> +
> +enum AUD_PCM_AFIFO_SRC {
> +	/* slave mode & external modem uses different crystal */
> +	AUD_PCM_AFIFO_ASRC = 0,
> +	/* slave mode & external modem uses the same crystal */
> +	AUD_PCM_AFIFO_AFIFO = 1
> +};
> +
> +enum AUD_PCM_CLOCK_SOURCE {
> +	AUD_PCM_CLOCK_MASTER_MODE = 0,
> +	AUD_PCM_CLOCK_SLAVE_MODE = 1
> +};
> +
> +enum AUD_PCM_WLEN {
> +	AUD_PCM_WLEN_PCM_32_BCK_CYCLES = 0,
> +	AUD_PCM_WLEN_PCM_64_BCK_CYCLES = 1
> +};
> +
> +enum AUD_PCM_24BIT {
> +	AUD_PCM_24BIT_PCM_16_BITS = 0,
> +	AUD_PCM_24BIT_PCM_24_BITS = 1
> +};
> +
> +enum AUD_PCM_MODE {
> +	AUD_PCM_MODE_PCM_MODE_8K = 0,
> +	AUD_PCM_MODE_PCM_MODE_16K = 1,
> +	AUD_PCM_MODE_PCM_MODE_32K = 2,
> +	AUD_PCM_MODE_PCM_MODE_48K = 3,
> +};
> +
> +enum AUD_PCM_FMT {
> +	AUD_PCM_FMT_I2S = 0,
> +	AUD_PCM_FMT_EIAJ = 1,
> +	AUD_PCM_FMT_PCM_MODE_A = 2,
> +	AUD_PCM_FMT_PCM_MODE_B = 3
> +};
> +
> +enum AUD_BCLK_OUT_INV {
> +	AUD_BCLK_OUT_INV_NO_INVERSE = 0,
> +	AUD_BCLK_OUT_INV_INVERSE = 1
> +};
> +
> +enum AUD_LRCLK_OUT_INV {
> +	AUD_LRCLK_OUT_INV_NO_INVERSE = 0,
> +	AUD_LRCLK_OUT_INV_INVERSE = 1
> +};
> +
> +enum AUD_PCM_EN {
> +	AUD_PCM_EN_DISABLE = 0,
> +	AUD_PCM_EN_ENABLE = 1
> +};
> +

..snip..

> +
> +/* dai ops */
> +static int mtk_dai_pcm_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int pcm_id = dai->id;
> +	struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[pcm_id];
> +	unsigned int rate = params_rate(params);
> +	unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, dai->id);
> +	snd_pcm_format_t format = params_format(params);
> +	unsigned int data_width =
> +		snd_pcm_format_width(format);
> +	unsigned int wlen_width =
> +		snd_pcm_format_physical_width(format);
> +	unsigned int pcm_con = 0;
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d, widget active p %d, c %d\n",
> +		 __func__,
> +		 dai->id,
> +		 substream->stream,
> +		 dai->playback_widget->active,
> +		 dai->capture_widget->active);
> +	dev_info(afe->dev, "%s(), rate %d, rate_reg %d, data_width %d, wlen_width %d\n",
> +		 __func__,
> +		 rate,
> +		 rate_reg,
> +		 data_width,
> +		 wlen_width);

dev_dbg() - also, you don't need one line per variable.

> +
> +	if (dai->playback_widget->active || dai->capture_widget->active)
> +		return 0;
> +
> +	switch (dai->id) {
> +	case MT8186_DAI_PCM:
> +		pcm_con |= AUD_TX_LCH_RPT_NO_REPEAT << PCM_TX_LCH_RPT_SFT;
> +		pcm_con |= AUD_VBT_16K_MODE_DISABLE << PCM_VBT_16K_MODE_SFT;
> +		pcm_con |= AUD_EXT_MODEM_SELECT_EXTERNAL << PCM_EXT_MODEM_SFT;
> +		pcm_con |= AUD_PCM_ONE_BCK_CYCLE_SYNC << PCM_SYNC_TYPE_SFT;
> +		pcm_con |= AUD_BT_MODE_DUAL_MIC_ON_TX << PCM_BT_MODE_SFT;
> +		pcm_con |= AUD_PCM_AFIFO_AFIFO << PCM_BYP_ASRC_SFT;
> +		pcm_con |= AUD_PCM_CLOCK_MASTER_MODE << PCM_SLAVE_SFT;
> +		pcm_con |= 0 << PCM_SYNC_LENGTH_SFT;
> +
> +		/* sampling rate */
> +		pcm_con |= rate_reg << PCM_MODE_SFT;
> +
> +		/* format */
> +		pcm_con |= pcm_priv->fmt << PCM_FMT_SFT;
> +
> +		/* 24bit data width */
> +		if (data_width > 16)
> +			pcm_con |= AUD_PCM_24BIT_PCM_24_BITS << PCM_24BIT_SFT;
> +		else
> +			pcm_con |= AUD_PCM_24BIT_PCM_16_BITS << PCM_24BIT_SFT;
> +
> +		/* wlen width*/
> +		if (wlen_width > 16)
> +			pcm_con |= AUD_PCM_WLEN_PCM_64_BCK_CYCLES << PCM_WLEN_SFT;
> +		else
> +			pcm_con |= AUD_PCM_WLEN_PCM_32_BCK_CYCLES << PCM_WLEN_SFT;
> +
> +		/* clock invert */
> +		pcm_con |= pcm_priv->lck_invert << PCM_SYNC_OUT_INV_SFT;
> +		pcm_con |= pcm_priv->bck_invert << PCM_BCLK_OUT_INV_SFT;
> +
> +		regmap_update_bits(afe->regmap, PCM_INTF_CON1,
> +				   0xfffffffe, pcm_con);

Fits in one line.

> +		break;
> +	default:
> +		dev_info(afe->dev, "%s(), id %d not support\n",
> +			 __func__, dai->id);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[dai->id];
> +
> +	if (!pcm_priv) {
> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #6
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 i2s dai driver
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-dai-i2s.c | 1371 ++++++++++++++++++++
>   1 file changed, 1371 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> new file mode 100644
> index 000000000000..d6db5f6a7315
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> @@ -0,0 +1,1371 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI I2S Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/bitops.h>
> +#include <linux/regmap.h>
> +#include <sound/pcm_params.h>
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-gpio.h"
> +#include "mt8186-interconnection.h"
> +
> +enum {
> +	I2S_FMT_EIAJ = 0,
> +	I2S_FMT_I2S = 1,
> +};
> +
> +enum {
> +	I2S_WLEN_16_BIT = 0,
> +	I2S_WLEN_32_BIT = 1,
> +};
> +
> +enum {
> +	I2S_HD_NORMAL = 0,
> +	I2S_HD_LOW_JITTER = 1,
> +};
> +
> +enum {
> +	I2S1_SEL_O28_O29 = 0,
> +	I2S1_SEL_O03_O04 = 1,
> +};
> +
> +enum {
> +	I2S_IN_PAD_CONNSYS = 0,
> +	I2S_IN_PAD_IO_MUX = 1,
> +};
> +
> +struct mtk_afe_i2s_priv {
> +	int id;
> +	int rate; /* for determine which apll to use */
> +	int low_jitter_en;
> +	int master; /* only i2s0 has slave mode*/
> +
> +	const char *share_property_name;
> +	int share_i2s_id;
> +
> +	int mclk_id;
> +	int mclk_rate;
> +	int mclk_apll;
> +};
> +
> +static unsigned int get_i2s_wlen(snd_pcm_format_t format)
> +{
> +	return snd_pcm_format_physical_width(format) <= 16 ?
> +	       I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
> +}
> +
> +#define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
> +#define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
> +#define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
> +#define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
> +#define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"
> +
> +#define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
> +#define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
> +#define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
> +#define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
> +
> +#define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
> +#define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
> +#define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
> +#define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
> +
> +static int get_i2s_id_by_name(struct mtk_base_afe *afe,
> +			      const char *name)
> +{
> +	if (strncmp(name, "I2S0", 4) == 0)
> +		return MT8186_DAI_I2S_0;
> +	else if (strncmp(name, "I2S1", 4) == 0)
> +		return MT8186_DAI_I2S_1;
> +	else if (strncmp(name, "I2S2", 4) == 0)
> +		return MT8186_DAI_I2S_2;
> +	else if (strncmp(name, "I2S3", 4) == 0)
> +		return MT8186_DAI_I2S_3;

This is just

	return -EINVAL;

(without the "else").

> +	else
> +		return -EINVAL;
> +}
> +
> +static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
> +						     const char *name)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int dai_id = get_i2s_id_by_name(afe, name);
> +
> +	if (dai_id < 0)
> +		return NULL;
> +
> +	return afe_priv->dai_priv[dai_id];
> +}
> +
> +/* low jitter control */
> +static const char * const mt8186_i2s_hd_str[] = {
> +	"Normal", "Low_Jitter"
> +};
> +
> +static const struct soc_enum mt8186_i2s_enum[] = {
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),
> +			    mt8186_i2s_hd_str),
> +};
> +
> +/* clock source control */
> +static const char * const mt8186_i2s_src_str[] = {
> +	"Master", "Slave"
> +};
> +
> +static const struct soc_enum mt8186_i2s_src_enum[] = {
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_src_str),
> +			    mt8186_i2s_src_str),
> +};
> +
> +static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
> +			     struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
> +
> +	return 0;
> +}
> +
> +static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
> +			     struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int hd_en;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	hd_en = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
> +		 __func__, kcontrol->id.name, hd_en);

dev_dbg()

> +
> +	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	i2s_priv->low_jitter_en = hd_en;
> +
> +	return 0;
> +}
> +
> +static int mt8186_i2s_src_get(struct snd_kcontrol *kcontrol,
> +			      struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	ucontrol->value.integer.value[0] = i2s_priv->master;
> +
> +	return 0;
> +}
> +
> +static int mt8186_i2s_src_set(struct snd_kcontrol *kcontrol,
> +			      struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int clk_src;
> +	int dai_id;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	clk_src = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
> +		 __func__, kcontrol->id.name, clk_src);

dev_dbg()

> +
> +	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
> +	dai_id = get_i2s_id_by_name(afe, kcontrol->id.name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	switch (dai_id) {
> +	case MT8186_DAI_I2S_0:
> +		regmap_update_bits(afe->regmap, AFE_I2S_CON,
> +				   I2S_SRC_MASK_SFT,
> +				   clk_src << I2S_SRC_SFT);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	i2s_priv->master = clk_src;
> +
> +	return 0;
> +}
> +

..snip..

> +
> +static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,
> +			    struct snd_kcontrol *kcontrol,
> +			    int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, w->name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_apll_event(struct snd_soc_dapm_widget *w,
> +			  struct snd_kcontrol *kcontrol,
> +			  int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		if (strcmp(w->name, APLL1_W_NAME) == 0)
> +			mt8186_apll1_enable(afe);
> +		else
> +			mt8186_apll2_enable(afe);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		if (strcmp(w->name, APLL1_W_NAME) == 0)
> +			mt8186_apll1_disable(afe);
> +		else
> +			mt8186_apll2_disable(afe);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
> +			     struct snd_kcontrol *kcontrol,
> +			     int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, w->name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		i2s_priv->mclk_rate = 0;
> +		mt8186_mck_disable(afe, i2s_priv->mclk_id);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +

..snip..

> +
> +static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
> +				     struct snd_soc_dapm_widget *sink)
> +{
> +	struct snd_soc_dapm_widget *w = sink;
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

Is this an error? => dev_err()
Is this expected? => dev_dbg()

> +		return 0;
> +	}
> +
> +	if (i2s_priv->share_i2s_id < 0)
> +		return 0;
> +
> +	return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
> +}
> +
> +static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
> +				  struct snd_soc_dapm_widget *sink)
> +{
> +	struct snd_soc_dapm_widget *w = sink;
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mtk_afe_i2s_priv *i2s_priv;
> +
> +	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

Is this an error? => dev_err()
Is this expected? => dev_dbg()

Please fix all of the other instances of this.

> +		return 0;
> +	}
> +
> +	if (get_i2s_id_by_name(afe, sink->name) ==
> +	    get_i2s_id_by_name(afe, source->name))
> +		return i2s_priv->low_jitter_en;
> +
> +	/* check if share i2s need hd en */
> +	if (i2s_priv->share_i2s_id < 0)
> +		return 0;
> +
> +	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
> +		return i2s_priv->low_jitter_en;
> +
> +	return 0;
> +}
> +

..snip...

> +
> +/* dai ops */
> +static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,
> +					 struct snd_pcm_hw_params *params,
> +					 struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	unsigned int rate = params_rate(params);
> +	unsigned int rate_reg = mt8186_rate_transform(afe->dev,
> +						      rate, dai->id);
> +	unsigned int i2s_con = 0;
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> +		 __func__,
> +		 dai->id,
> +		 substream->stream,
> +		 rate);
> +
> +	/* non-inverse, i2s mode, slave, 16bits, from connsys */
> +	i2s_con |= 0 << INV_PAD_CTRL_SFT;
> +	i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
> +	i2s_con |= 1 << I2S_SRC_SFT;
> +	i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;
> +	i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
> +	regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
> +
> +	/* use asrc */
> +	regmap_update_bits(afe->regmap,
> +			   AFE_CONNSYS_I2S_CON,
> +			   I2S_BYPSRC_MASK_SFT,
> +			   0x0 << I2S_BYPSRC_SFT);

Zero shifted of a billion bits is still zero.

regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON, I2S_BYPSRC_MASK_SFT, 0);

> +
> +	/* slave mode, set i2s for asrc */
> +	regmap_update_bits(afe->regmap,
> +			   AFE_CONNSYS_I2S_CON,
> +			   I2S_MODE_MASK_SFT,
> +			   rate_reg << I2S_MODE_SFT);

	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,

			   I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);

> +
> +	if (rate == 44100)
> +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x001B9000);

lower case hex, please, and no leading zeros.

> +	else if (rate == 32000)
> +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
> +	else
> +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x001E0000);
> +
> +	/* Calibration setting */
> +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x00140000);
> +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x00036000);
> +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x0002FC00);
> +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x00007EF4);
> +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0x00FF5986);

ditto.

> +
> +	/* 0:Stereo 1:Mono */
> +	regmap_update_bits(afe->regmap,
> +			   AFE_ASRC_2CH_CON2,
> +			   CHSET_IS_MONO_MASK_SFT,
> +			   0x0 << CHSET_IS_MONO_SFT);

0 << SOMETHING = 0

Also, this fits in one line.

> +
> +	return 0;
> +}
> +
> +static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,
> +				       int cmd, struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	dev_info(afe->dev, "%s(), cmd %d, stream %d\n",
> +		 __func__,
> +		 cmd,
> +		 substream->stream);

dev_dbg(), also fits in two lines.

> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +		/* i2s enable */
> +		regmap_update_bits(afe->regmap,
> +				   AFE_CONNSYS_I2S_CON,
> +				   I2S_EN_MASK_SFT,
> +				   0x1 << I2S_EN_SFT);

BIT()

> +
> +		/* calibrator enable */
> +		regmap_update_bits(afe->regmap,
> +				   AFE_ASRC_2CH_CON5,
> +				   CALI_EN_MASK_SFT,
> +				   0x1 << CALI_EN_SFT);

BIT()

> +
> +		/* asrc enable */
> +		regmap_update_bits(afe->regmap,
> +				   AFE_ASRC_2CH_CON0,
> +				   CON0_CHSET_STR_CLR_MASK_SFT,
> +				   0x1 << CON0_CHSET_STR_CLR_SFT);

BIT()

> +		regmap_update_bits(afe->regmap,
> +				   AFE_ASRC_2CH_CON0,
> +				   CON0_ASM_ON_MASK_SFT,
> +				   0x1 << CON0_ASM_ON_SFT);

BIT()

> +
> +		afe_priv->dai_on[dai->id] = true;
> +		return 0;
> +	case SNDRV_PCM_TRIGGER_STOP:
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +		regmap_update_bits(afe->regmap,
> +				   AFE_ASRC_2CH_CON0,
> +				   CON0_ASM_ON_MASK_SFT,
> +				   0 << CON0_ASM_ON_SFT);

This is zero.

> +		regmap_update_bits(afe->regmap,
> +				   AFE_ASRC_2CH_CON5,
> +				   CALI_EN_MASK_SFT,
> +				   0 << CALI_EN_SFT);

Zero again.

> +
> +		/* i2s disable */
> +		regmap_update_bits(afe->regmap,
> +				   AFE_CONNSYS_I2S_CON,
> +				   I2S_EN_MASK_SFT,
> +				   0x0 << I2S_EN_SFT);

...and again.

> +
> +		/* bypass asrc */
> +		regmap_update_bits(afe->regmap,
> +				   AFE_CONNSYS_I2S_CON,
> +				   I2S_BYPSRC_MASK_SFT,
> +				   0x1 << I2S_BYPSRC_SFT);

BIT()

> +
> +		afe_priv->dai_on[dai->id] = false;
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +	return 0;
> +}
> +
> +static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {
> +	.hw_params = mtk_dai_connsys_i2s_hw_params,
> +	.trigger = mtk_dai_connsys_i2s_trigger,
> +};
> +
> +/* i2s */
> +static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
> +			      struct snd_pcm_hw_params *params,
> +			      int i2s_id)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
> +
> +	unsigned int rate = params_rate(params);
> +	unsigned int rate_reg = mt8186_rate_transform(afe->dev,
> +						      rate, i2s_id);

Fits on a single line.

> +	snd_pcm_format_t format = params_format(params);
> +	unsigned int i2s_con = 0;
> +	int ret = 0;
> +
> +	dev_info(afe->dev, "%s(), id %d, rate %d, format %d\n",
> +		 __func__,
> +		 i2s_id,
> +		 rate, format);

dev_dbg(), fits on two lines.

> +
> +	if (i2s_priv)
> +		i2s_priv->rate = rate;
> +	else
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

I'm not sure about this print, maybe this should also be dev_dbg()

> +
> +	switch (i2s_id) {
> +	case MT8186_DAI_I2S_0:
> +		i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
> +		i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
> +		i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
> +		i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
> +		regmap_update_bits(afe->regmap, AFE_I2S_CON,
> +				   0xffffeffa, i2s_con);
> +		break;
> +	case MT8186_DAI_I2S_1:
> +		i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
> +		i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
> +		i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
> +		i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
> +		regmap_update_bits(afe->regmap, AFE_I2S_CON1,
> +				   0xffffeffa, i2s_con);
> +		break;
> +	case MT8186_DAI_I2S_2:
> +		i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
> +		i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
> +		i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
> +		i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
> +		regmap_update_bits(afe->regmap, AFE_I2S_CON2,
> +				   0xffffeffa, i2s_con);
> +		break;
> +	case MT8186_DAI_I2S_3:
> +		i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
> +		i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
> +		i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
> +		regmap_update_bits(afe->regmap, AFE_I2S_CON3,
> +				   0xffffeffa, i2s_con);
> +		break;
> +	default:
> +		dev_info(afe->dev, "%s(), id %d not support\n",
> +			 __func__, i2s_id);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	/* set share i2s */
> +	if (i2s_priv && i2s_priv->share_i2s_id >= 0)
> +		ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
> +

	if (i2s_priv && i2s_priv->share_i2s_id >= 0) {

		ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);

		if (ret)

			return ret;

	}



	return 0;

> +	return ret;
> +}
> +
> +static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +
> +	return mtk_dai_i2s_config(afe, params, dai->id);
> +}
> +
> +static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
> +				  int clk_id, unsigned int freq, int dir)
> +{
> +	struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
> +	int apll;
> +	int apll_rate;
> +
> +	if (!i2s_priv) {
> +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	if (dir != SND_SOC_CLOCK_OUT) {
> +		dev_info(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);

again...

> +		return -EINVAL;
> +	}
> +
> +	dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);

dev_dbg()

> +
> +	apll = mt8186_get_apll_by_rate(afe, freq);
> +	apll_rate = mt8186_get_apll_rate(afe, apll);
> +
> +	if (freq > apll_rate) {
> +		dev_info(afe->dev, "%s(), freq > apll rate", __func__);

dev_err() .... please fix the rest as well.

> +		return -EINVAL;
> +	}
> +
> +	if (apll_rate % freq != 0) {
> +		dev_info(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);
> +		return -EINVAL;
> +	}
> +
> +	i2s_priv->mclk_rate = freq;
> +	i2s_priv->mclk_apll = apll;
> +
> +	if (i2s_priv->share_i2s_id > 0) {
> +		struct mtk_afe_i2s_priv *share_i2s_priv;
> +
> +		share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
> +		if (!share_i2s_priv) {
> +			dev_info(afe->dev, "%s(), share_i2s_priv == NULL", __func__);
> +			return -EINVAL;
> +		}
> +
> +		share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
> +		share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
> +	}
> +
> +	return 0;
> +}
> +

Regards,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #7
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 tdm dai driver.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 713 +++++++++++++++++++++
>   1 file changed, 713 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> new file mode 100644
> index 000000000000..28dd3661f0e0
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> @@ -0,0 +1,713 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio DAI TDM Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/regmap.h>
> +#include <sound/pcm_params.h>
> +
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-gpio.h"
> +#include "mt8186-interconnection.h"
> +
> +#define TDM_HD_EN_W_NAME "TDM_HD_EN"
> +#define TDM_MCLK_EN_W_NAME "TDM_MCLK_EN"
> +#define MTK_AFE_TDM_KCONTROL_NAME "TDM_HD_Mux"
> +
> +struct mtk_afe_tdm_priv {
> +	unsigned int id;
> +	unsigned int rate; /* for determine which apll to use */
> +	unsigned int bck_invert;
> +	unsigned int lck_invert;
> +	unsigned int lrck_width;
> +	unsigned int mclk_id;
> +	unsigned int mclk_multiple; /* according to sample rate */
> +	unsigned int mclk_rate;
> +	unsigned int mclk_apll;
> +	unsigned int tdm_mode;
> +	unsigned int data_mode;
> +	unsigned int slave_mode;
> +	unsigned int low_jitter_en;
> +};
> +
> +enum {
> +	TDM_IN_I2S = 0,
> +	TDM_IN_LJ = 1,
> +	TDM_IN_RJ = 2,
> +	TDM_IN_DSP_A = 4,
> +	TDM_IN_DSP_B = 5,
> +};
> +
> +enum {
> +	TDM_DATA_ONE_PIN = 0,
> +	TDM_DATA_MULTI_PIN,
> +};
> +
> +enum {
> +	TDM_BCK_NON_INV = 0,
> +	TDM_BCK_INV = 1,
> +};
> +
> +enum {
> +	TDM_LCK_NON_INV = 0,
> +	TDM_LCK_INV = 1,
> +};
> +
> +static unsigned int get_tdm_lrck_width(snd_pcm_format_t format,
> +				       unsigned int mode)
> +{
> +	if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B)
> +		return 0;
> +	else

Drop the "else"

> +		return snd_pcm_format_physical_width(format) - 1;
> +}
> +
> +static unsigned int get_tdm_ch_fixup(unsigned int channels)
> +{
> +	if (channels > 4)
> +		return 8;
> +	else if (channels > 2)
> +		return 4;
> +	else

Same here

> +		return 2;
> +}
> +
> +static unsigned int get_tdm_ch_per_sdata(unsigned int mode,
> +					 unsigned int channels)
> +{
> +	if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B)
> +		return get_tdm_ch_fixup(channels);
> +	else

...and same here

> +		return 2;
> +}
> +
> +enum {
> +	SUPPLY_SEQ_APLL,
> +	SUPPLY_SEQ_TDM_MCK_EN,
> +	SUPPLY_SEQ_TDM_HD_EN,
> +	SUPPLY_SEQ_TDM_EN,
> +};
> +
> +static int get_tdm_id_by_name(const char *name)
> +{
> +	return MT8186_DAI_TDM_IN;
> +}
> +
> +static int mtk_tdm_en_event(struct snd_soc_dapm_widget *w,
> +			    struct snd_kcontrol *kcontrol,
> +			    int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int dai_id = get_tdm_id_by_name(w->name);
> +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> +
> +	if (!tdm_priv) {
> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> +		__func__, w->name, event);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		mt8186_afe_gpio_request(afe->dev, true, tdm_priv->id, 0);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		mt8186_afe_gpio_request(afe->dev, false, tdm_priv->id, 0);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w,
> +				struct snd_kcontrol *kcontrol,
> +				int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int dai_id = get_tdm_id_by_name(w->name);
> +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> +
> +	if (!tdm_priv) {
> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);

dev_err() - please fix all other instances

> +		return -EINVAL;
> +	}
> +
> +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n",
> +		__func__, w->name, event, dai_id);
> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		mt8186_mck_enable(afe, tdm_priv->mclk_id, tdm_priv->mclk_rate);
> +		break;
> +	case SND_SOC_DAPM_POST_PMD:
> +		tdm_priv->mclk_rate = 0;
> +		mt8186_mck_disable(afe, tdm_priv->mclk_id);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +

...snip...

> +
> +static int mt8186_tdm_hd_set(struct snd_kcontrol *kcontrol,
> +			     struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int dai_id = get_tdm_id_by_name(kcontrol->id.name);
> +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int hd_en;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	hd_en = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
> +		 __func__, kcontrol->id.name, hd_en);

dev_dbg()

> +
> +	if (!tdm_priv) {
> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> +		return -EINVAL;
> +	}
> +
> +	tdm_priv->low_jitter_en = hd_en;
> +
> +	return 0;
> +}
> +
> +static const struct snd_kcontrol_new mtk_dai_tdm_controls[] = {
> +	SOC_ENUM_EXT(MTK_AFE_TDM_KCONTROL_NAME, mt8186_tdm_enum[0],
> +		     mt8186_tdm_hd_get, mt8186_tdm_hd_set),
> +};
> +
> +static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = {
> +	{"TDM IN", NULL, "aud_tdm_clk"},
> +	{"TDM IN", NULL, "TDM_EN"},
> +	{"TDM IN", NULL, TDM_HD_EN_W_NAME, mtk_afe_tdm_hd_connect},
> +	{TDM_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_apll_connect},
> +	{TDM_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_apll_connect},
> +
> +	{"TDM IN", NULL, TDM_MCLK_EN_W_NAME, mtk_afe_tdm_mclk_connect},
> +	{TDM_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_tdm_mclk_apll_connect},
> +	{TDM_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_tdm_mclk_apll_connect},
> +
> +	/* allow tdm on without codec on */
> +	{"TDM IN", NULL, "TDM_In_Mux"},
> +	{"TDM_In_Mux", "Dummy_Widget", "TDM_DUMMY_IN"},
> +};
> +
> +/* dai ops */
> +static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe,
> +				struct mtk_afe_tdm_priv *tdm_priv,
> +				int freq)
> +{
> +	int apll;
> +	int apll_rate;
> +
> +	apll = mt8186_get_apll_by_rate(afe, freq);
> +	apll_rate = mt8186_get_apll_rate(afe, apll);
> +
> +	if (!freq || freq > apll_rate) {
> +		dev_info(afe->dev,
> +			 "%s(), freq(%d Hz) invalid\n", __func__, freq);
> +		return -EINVAL;
> +	}
> +
> +	if (apll_rate % freq != 0) {
> +		dev_info(afe->dev,
> +			 "%s(), APLL cannot generate %d Hz", __func__, freq);
> +		return -EINVAL;
> +	}
> +
> +	tdm_priv->mclk_rate = freq;
> +	tdm_priv->mclk_apll = apll;
> +
> +	return 0;
> +}
> +
> +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int tdm_id = dai->id;
> +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
> +	unsigned int tdm_mode = tdm_priv->tdm_mode;
> +	unsigned int data_mode = tdm_priv->data_mode;
> +	unsigned int rate = params_rate(params);
> +	unsigned int channels = params_channels(params);
> +	snd_pcm_format_t format = params_format(params);
> +	unsigned int bit_width =
> +		snd_pcm_format_physical_width(format);
> +	unsigned int tdm_channels = (data_mode == TDM_DATA_ONE_PIN) ?
> +		get_tdm_ch_per_sdata(tdm_mode, channels) : 2;
> +	unsigned int lrck_width =
> +		get_tdm_lrck_width(format, tdm_mode);
> +	unsigned int tdm_con = 0;
> +	bool slave_mode = tdm_priv->slave_mode;
> +	bool lrck_inv = tdm_priv->lck_invert;
> +	bool bck_inv = tdm_priv->bck_invert;
> +	unsigned int ctrl_reg;
> +	unsigned int ctrl_mask;
> +	unsigned int tran_rate;
> +	unsigned int tran_relatch_rate;
> +
> +	if (tdm_priv)
> +		tdm_priv->rate = rate;
> +	else
> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> +
> +	tran_rate = mt8186_rate_transform(afe->dev, rate, dai->id);
> +	tran_relatch_rate = mt8186_tdm_relatch_rate_transform(afe->dev, rate);
> +
> +	/* calculate mclk_rate, if not set explicitly */
> +	if (!tdm_priv->mclk_rate) {
> +		tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple;
> +		mtk_dai_tdm_cal_mclk(afe,
> +				     tdm_priv,
> +				     tdm_priv->mclk_rate);
> +	}
> +
> +	/* ETDM_IN1_CON0 */
> +	tdm_con |= slave_mode << ETDM_IN1_CON0_REG_SLAVE_MODE_SFT;
> +	tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT;
> +	tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_BIT_LENGTH_SFT;
> +	tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_WORD_LENGTH_SFT;
> +	tdm_con |= (tdm_channels - 1) << ETDM_IN1_CON0_REG_CH_NUM_SFT;
> +	/* default disable sync mode */
> +	tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT;

0 << (anything) == 0

(number |= 0) == number

Is this a mistake, or are you really doing nothing here?


> +	/* relatch fix to h26m */
> +	tdm_con |= 0 << ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT;
> +
> +	ctrl_reg = ETDM_IN1_CON0;
> +	ctrl_mask = ETDM_IN_CON0_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> +
> +	/* ETDM_IN1_CON1 */
> +	tdm_con = 0;
> +	tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT;
> +	tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT;
> +	tdm_con |= (lrck_width - 1) << ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT;
> +
> +	ctrl_reg = ETDM_IN1_CON1;
> +	ctrl_mask = ETDM_IN_CON1_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);

You don't need the ctrl_reg, nor ctrl_mask variables...

regmap_update_bits(afe->regmap, ETDM_IN1_CON1, ETDM_IN_CON1_CTRL_MASK, tdm_con);

> +
> +	/* ETDM_IN1_CON3 */
> +	tdm_con = 0;
> +	tdm_con = ETDM_IN_CON3_FS(tran_rate);
> +
> +	ctrl_reg = ETDM_IN1_CON3;
> +	ctrl_mask = ETDM_IN_CON3_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);

same here

> +
> +	/* ETDM_IN1_CON4 */
> +	tdm_con = 0;
> +	tdm_con = ETDM_IN_CON4_FS(tran_relatch_rate);
> +	if (slave_mode) {
> +		if (lrck_inv)
> +			tdm_con |= ETDM_IN_CON4_CON0_SLAVE_LRCK_INV;
> +		if (bck_inv)
> +			tdm_con |= ETDM_IN_CON4_CON0_SLAVE_BCK_INV;
> +	} else {
> +		if (lrck_inv)
> +			tdm_con |= ETDM_IN_CON4_CON0_MASTER_LRCK_INV;
> +		if (bck_inv)
> +			tdm_con |= ETDM_IN_CON4_CON0_MASTER_BCK_INV;
> +	}
> +
> +	ctrl_reg = ETDM_IN1_CON4;
> +	ctrl_mask = ETDM_IN_CON4_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);

and here

> +
> +	/* ETDM_IN1_CON2 */
> +	tdm_con = 0;
> +	if (data_mode == TDM_DATA_MULTI_PIN) {
> +		tdm_con |= ETDM_IN_CON2_MULTI_IP_2CH_MODE;
> +		tdm_con |= ETDM_IN_CON2_MULTI_IP_CH(channels);
> +	}
> +
> +	ctrl_reg = ETDM_IN1_CON2;
> +	ctrl_mask = ETDM_IN_CON2_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);

and here

> +
> +	/* ETDM_IN1_CON8 */
> +	tdm_con = 0;
> +	if (slave_mode) {
> +		tdm_con |= 1 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT;
> +		tdm_con |= 0 << ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT;
> +		tdm_con |= ETDM_IN_CON8_FS(tran_relatch_rate);
> +	} else {
> +		tdm_con |= 0 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT;
> +	}
> +
> +	ctrl_reg = ETDM_IN1_CON8;
> +	ctrl_mask = ETDM_IN_CON8_CTRL_MASK;
> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);

finally, here too.

> +
> +	return 0;
> +}
> +

Thanks,
ANgelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #8
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch add audio clock control with CCF interface.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-afe-clk.c | 719 +++++++++++++++++++++
>   sound/soc/mediatek/mt8186/mt8186-afe-clk.h | 210 ++++++
>   2 files changed, 929 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.c
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> new file mode 100644
> index 000000000000..14f64b935619
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> @@ -0,0 +1,719 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// mt8186-afe-clk.c  --  Mediatek 8186 afe clock ctrl
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/clk.h>
> +#include <linux/regmap.h>
> +#include <linux/mfd/syscon.h>
> +
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-audsys-clk.h"
> +
> +static DEFINE_MUTEX(mutex_request_dram);
> +
> +static const char *aud_clks[CLK_NUM] = {
> +	[CLK_AFE] = "aud_afe_clk",
> +	[CLK_DAC] = "aud_dac_clk",
> +	[CLK_DAC_PREDIS] = "aud_dac_predis_clk",
> +	[CLK_ADC] = "aud_adc_clk",
> +	[CLK_TML] = "aud_tml_clk",
> +	[CLK_APLL22M] = "aud_apll22m_clk",
> +	[CLK_APLL24M] = "aud_apll24m_clk",
> +	[CLK_APLL1_TUNER] = "aud_apll_tuner_clk",
> +	[CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",
> +	[CLK_TDM] = "aud_tdm_clk",
> +	[CLK_NLE] = "aud_nle_clk",
> +	[CLK_DAC_HIRES] = "aud_dac_hires_clk",
> +	[CLK_ADC_HIRES] = "aud_adc_hires_clk",
> +	[CLK_I2S1_BCLK] = "aud_i2s1_bclk",
> +	[CLK_I2S2_BCLK] = "aud_i2s2_bclk",
> +	[CLK_I2S3_BCLK] = "aud_i2s3_bclk",
> +	[CLK_I2S4_BCLK] = "aud_i2s4_bclk",
> +	[CLK_CONNSYS_I2S_ASRC] = "aud_connsys_i2s_asrc",
> +	[CLK_GENERAL1_ASRC] = "aud_general1_asrc",
> +	[CLK_GENERAL2_ASRC] = "aud_general2_asrc",
> +	[CLK_ADC_HIRES_TML] = "aud_adc_hires_tml",
> +	[CLK_ADDA6_ADC] = "aud_adda6_adc",
> +	[CLK_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires",
> +	[CLK_3RD_DAC] = "aud_3rd_dac",
> +	[CLK_3RD_DAC_PREDIS] = "aud_3rd_dac_predis",
> +	[CLK_3RD_DAC_TML] = "aud_3rd_dac_tml",
> +	[CLK_3RD_DAC_HIRES] = "aud_3rd_dac_hires",
> +	[CLK_ETDM_IN1_BCLK] = "aud_etdm_in1_bclk",
> +	[CLK_ETDM_OUT1_BCLK] = "aud_etdm_out1_bclk",
> +	[CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",
> +	[CLK_INFRA_AUDIO_26M] = "mtkaif_26m_clk",
> +	[CLK_MUX_AUDIO] = "top_mux_audio",
> +	[CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int",
> +	[CLK_TOP_MAINPLL_D2_D4] = "top_mainpll_d2_d4",
> +	[CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",
> +	[CLK_TOP_APLL1_CK] = "top_apll1_ck",
> +	[CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",
> +	[CLK_TOP_APLL2_CK] = "top_apll2_ck",
> +	[CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",
> +	[CLK_TOP_APLL1_D8] = "top_apll1_d8",
> +	[CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",
> +	[CLK_TOP_APLL2_D8] = "top_apll2_d8",
> +	[CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h",
> +	[CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",
> +	[CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",
> +	[CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",
> +	[CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",
> +	[CLK_TOP_TDM_M_SEL] = "top_tdm_m_sel",
> +	[CLK_TOP_APLL12_DIV0] = "top_apll12_div0",
> +	[CLK_TOP_APLL12_DIV1] = "top_apll12_div1",
> +	[CLK_TOP_APLL12_DIV2] = "top_apll12_div2",
> +	[CLK_TOP_APLL12_DIV4] = "top_apll12_div4",
> +	[CLK_TOP_APLL12_DIV_TDM] = "top_apll12_div_tdm",
> +	[CLK_CLK26M] = "top_clk26m_clk",
> +};
> +
> +int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe,
> +				    int clk_id)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],
> +			     afe_priv->clk[clk_id]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS],
> +			 aud_clks[clk_id], ret);

		dev_err(......)
		return ret;

> +	}
> +

	return 0;

> +	return ret;
> +}
> +
> +static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret = 0;
> +
> +	if (enable) {
> +		ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1], ret);
> +			goto EXIT;
> +		}
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> +				     afe_priv->clk[CLK_TOP_APLL1_CK]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> +				 aud_clks[CLK_TOP_APLL1_CK], ret);

dev_err()

> +			goto EXIT;
> +		}
> +
> +		/* 180.6336 / 8 = 22.5792MHz */
> +		ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);
> +			goto EXIT;
> +		}
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
> +				     afe_priv->clk[CLK_TOP_APLL1_D8]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
> +				 aud_clks[CLK_TOP_APLL1_D8], ret);
> +			goto EXIT;
> +		}
> +	} else {
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
> +				     afe_priv->clk[CLK_CLK26M]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
> +				 aud_clks[CLK_CLK26M], ret);
> +			goto EXIT;
> +		}
> +		clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
> +
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> +				     afe_priv->clk[CLK_CLK26M]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> +				 aud_clks[CLK_CLK26M], ret);
> +			goto EXIT;
> +		}
> +		clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
> +	}
> +EXIT:
> +	return 0;

You're returning 0 even in error cases, this is wrong.

> +}
> +
> +static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret = 0;
> +
> +	if (enable) {
> +		ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2], ret);
> +			goto EXIT;
> +		}
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> +				     afe_priv->clk[CLK_TOP_APLL2_CK]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> +				 aud_clks[CLK_TOP_APLL2_CK], ret);
> +			goto EXIT;
> +		}
> +
> +		/* 196.608 / 8 = 24.576MHz */
> +		ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);
> +			goto EXIT;
> +		}
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
> +				     afe_priv->clk[CLK_TOP_APLL2_D8]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
> +				 aud_clks[CLK_TOP_APLL2_D8], ret);
> +			goto EXIT;
> +		}
> +	} else {
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
> +				     afe_priv->clk[CLK_CLK26M]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
> +				 aud_clks[CLK_CLK26M], ret);
> +			goto EXIT;
> +		}
> +		clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
> +
> +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> +				     afe_priv->clk[CLK_CLK26M]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> +				 aud_clks[CLK_CLK26M], ret);
> +			goto EXIT;
> +		}
> +		clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
> +	}
> +
> +EXIT:
> +	return 0;
> +}
> +
> +int mt8186_afe_enable_cgs(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret = 0;
> +	int i;
> +
> +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) {
> +		ret = clk_prepare_enable(afe_priv->clk[i]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[i], ret);

dev_err()

> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +void mt8186_afe_disable_cgs(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int i;
> +
> +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++)
> +		clk_disable_unprepare(afe_priv->clk[i]);
> +}
> +
> +int mt8186_afe_enable_clock(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret = 0;
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);

dev_err()

> +		goto CLK_INFRA_SYS_AUDIO_ERR;

also, please use lower-case labels (here and everywhere else).

> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_INFRA_AUDIO_26M], ret);
> +		goto CLK_INFRA_AUDIO_26M_ERR;
> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIO], ret);
> +		goto CLK_MUX_AUDIO_ERR;
> +	}
> +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],
> +			     afe_priv->clk[CLK_CLK26M]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIO],
> +			 aud_clks[CLK_CLK26M], ret);
> +		goto CLK_MUX_AUDIO_ERR;
> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> +	}
> +	ret = mt8186_set_audio_int_bus_parent(afe,
> +					      CLK_TOP_MAINPLL_D2_D4);
> +	if (ret)
> +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> +
> +	ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H],
> +			     afe_priv->clk[CLK_TOP_APLL2_CK]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> +			 __func__, aud_clks[CLK_TOP_MUX_AUDIO_H],
> +			 aud_clks[CLK_TOP_APLL2_CK], ret);
> +		goto CLK_MUX_AUDIO_H_PARENT_ERR;
> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_AFE], ret);
> +		goto CLK_AFE_ERR;
> +	}
> +
> +	return 0;
> +
> +CLK_AFE_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> +CLK_MUX_AUDIO_H_PARENT_ERR:
> +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> +CLK_MUX_AUDIO_INTBUS_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +CLK_MUX_AUDIO_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> +CLK_INFRA_SYS_AUDIO_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> +CLK_INFRA_AUDIO_26M_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> +
> +	return ret;
> +}
> +
> +void mt8186_afe_disable_clock(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> +}
> +
> +int mt8186_afe_suspend_clock(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	/* set audio int bus to 26M */
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);

dev_err() - here and for the other similar instances.

> +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> +	}
> +	ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> +	if (ret)
> +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> +
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +
> +	return 0;
> +
> +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> +	mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4);
> +CLK_MUX_AUDIO_INTBUS_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	return ret;
> +}
> +
> +int mt8186_afe_resume_clock(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	/* set audio int bus to normal working clock */
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> +	}
> +	ret = mt8186_set_audio_int_bus_parent(afe,
> +					      CLK_TOP_MAINPLL_D2_D4);
> +	if (ret)
> +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> +
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +
> +	return 0;
> +
> +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> +CLK_MUX_AUDIO_INTBUS_ERR:
> +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> +	return ret;
> +}
> +
> +int mt8186_apll1_enable(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	/* setting for APLL */
> +	apll1_mux_setting(afe, true);
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_APLL22M], ret);
> +		goto ERR_CLK_APLL22M;
> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_APLL1_TUNER], ret);
> +		goto ERR_CLK_APLL1_TUNER;
> +	}
> +
> +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
> +			   0x0000FFF7, 0x00000832);

no leading zeroes - and without them, it fits in one line.

> +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);
> +
> +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> +			   AFE_22M_ON_MASK_SFT,
> +			   0x1 << AFE_22M_ON_SFT);

BIT() macro please

> +
> +	return 0;
> +
> +ERR_CLK_APLL1_TUNER:
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> +ERR_CLK_APLL22M:
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> +
> +	return ret;
> +}
> +
> +void mt8186_apll1_disable(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> +			   AFE_22M_ON_MASK_SFT,
> +			   0x0 << AFE_22M_ON_SFT);
> +
> +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0);
> +
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> +
> +	apll1_mux_setting(afe, false);
> +}
> +
> +int mt8186_apll2_enable(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	/* setting for APLL */
> +	apll2_mux_setting(afe, true);
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_APLL24M], ret);
> +		goto ERR_CLK_APLL24M;
> +	}
> +
> +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[CLK_APLL2_TUNER], ret);
> +		goto ERR_CLK_APLL2_TUNER;
> +	}
> +
> +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
> +			   0x0000FFF7, 0x00000634);
> +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);
> +
> +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> +			   AFE_24M_ON_MASK_SFT,
> +			   0x1 << AFE_24M_ON_SFT);
> +
> +	return 0;
> +
> +ERR_CLK_APLL2_TUNER:
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> +ERR_CLK_APLL24M:
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> +
> +	return ret;
> +}
> +
> +void mt8186_apll2_disable(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> +			   AFE_24M_ON_MASK_SFT,
> +			   0x0 << AFE_24M_ON_SFT);
> +
> +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0);
> +
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> +
> +	apll2_mux_setting(afe, false);
> +}
> +
> +int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll)
> +{
> +	return (apll == MT8186_APLL1) ? 180633600 : 196608000;
> +}
> +
> +int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
> +{
> +	return ((rate % 8000) == 0) ? MT8186_APLL2 : MT8186_APLL1;
> +}
> +
> +int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
> +{
> +	if (strcmp(name, APLL1_W_NAME) == 0)
> +		return MT8186_APLL1;
> +	else
> +		return MT8186_APLL2;
> +}
> +
> +/* mck */
> +struct mt8186_mck_div {
> +	int m_sel_id;
> +	int div_clk_id;
> +	/* below will be deprecated */
> +	int div_pdn_reg;
> +	int div_pdn_mask_sft;
> +	int div_reg;
> +	int div_mask_sft;
> +	int div_mask;
> +	int div_sft;
> +	int div_msb_reg;
> +	int div_msb_mask_sft;
> +	int div_msb_mask;
> +	int div_msb_sft;
> +	int div_apll_sel_reg;
> +	int div_apll_sel_mask_sft;
> +	int div_apll_sel_sft;
> +	int div_inv_reg;
> +	int div_inv_mask_sft;



*_reg fits in u16.
*_mask_sft, *_sel_sft can be u32.

This would be nice to avoid wasting memory for variables that are larger than
needed; besides, you're also using a signed type for a number that may not
ever be less than zero.


> +};
> +
> +static const struct mt8186_mck_div mck_div[MT8186_MCK_NUM] = {
> +	[MT8186_I2S0_MCK] = {
> +		.m_sel_id = CLK_TOP_I2S0_M_SEL,
> +		.div_clk_id = CLK_TOP_APLL12_DIV0,
> +		.div_pdn_reg = CLK_AUDDIV_0,
> +		.div_pdn_mask_sft = APLL12_DIV0_PDN_MASK_SFT,
> +		.div_reg = CLK_AUDDIV_2,
> +		.div_mask_sft = APLL12_CK_DIV0_MASK_SFT,
> +		.div_mask = APLL12_CK_DIV0_MASK,
> +		.div_sft = APLL12_CK_DIV0_SFT,
> +		.div_apll_sel_reg = CLK_AUDDIV_0,
> +		.div_apll_sel_mask_sft = APLL_I2S0_MCK_SEL_MASK_SFT,
> +		.div_apll_sel_sft = APLL_I2S0_MCK_SEL_SFT,
> +	},
> +	[MT8186_I2S1_MCK] = {
> +		.m_sel_id = CLK_TOP_I2S1_M_SEL,
> +		.div_clk_id = CLK_TOP_APLL12_DIV1,
> +		.div_pdn_reg = CLK_AUDDIV_0,
> +		.div_pdn_mask_sft = APLL12_DIV1_PDN_MASK_SFT,
> +		.div_reg = CLK_AUDDIV_2,
> +		.div_mask_sft = APLL12_CK_DIV1_MASK_SFT,
> +		.div_mask = APLL12_CK_DIV1_MASK,
> +		.div_sft = APLL12_CK_DIV1_SFT,
> +		.div_apll_sel_reg = CLK_AUDDIV_0,
> +		.div_apll_sel_mask_sft = APLL_I2S1_MCK_SEL_MASK_SFT,
> +		.div_apll_sel_sft = APLL_I2S1_MCK_SEL_SFT,
> +	},
> +	[MT8186_I2S2_MCK] = {
> +		.m_sel_id = CLK_TOP_I2S2_M_SEL,
> +		.div_clk_id = CLK_TOP_APLL12_DIV2,
> +		.div_pdn_reg = CLK_AUDDIV_0,
> +		.div_pdn_mask_sft = APLL12_DIV2_PDN_MASK_SFT,
> +		.div_reg = CLK_AUDDIV_2,
> +		.div_mask_sft = APLL12_CK_DIV2_MASK_SFT,
> +		.div_mask = APLL12_CK_DIV2_MASK,
> +		.div_sft = APLL12_CK_DIV2_SFT,
> +		.div_apll_sel_reg = CLK_AUDDIV_0,
> +		.div_apll_sel_mask_sft = APLL_I2S2_MCK_SEL_MASK_SFT,
> +		.div_apll_sel_sft = APLL_I2S2_MCK_SEL_SFT,
> +	},
> +	[MT8186_I2S4_MCK] = {
> +		.m_sel_id = CLK_TOP_I2S4_M_SEL,
> +		.div_clk_id = CLK_TOP_APLL12_DIV4,
> +		.div_pdn_reg = CLK_AUDDIV_0,
> +		.div_pdn_mask_sft = APLL12_DIV4_PDN_MASK_SFT,
> +		.div_reg = CLK_AUDDIV_2,
> +		.div_mask_sft = APLL12_CK_DIV4_MASK_SFT,
> +		.div_mask = APLL12_CK_DIV4_MASK,
> +		.div_sft = APLL12_CK_DIV4_SFT,
> +		.div_apll_sel_reg = CLK_AUDDIV_0,
> +		.div_apll_sel_mask_sft = APLL_I2S4_MCK_SEL_MASK_SFT,
> +		.div_apll_sel_sft = APLL_I2S4_MCK_SEL_SFT,
> +	},
> +	[MT8186_TDM_MCK] = {
> +		.m_sel_id = CLK_TOP_TDM_M_SEL,
> +		.div_clk_id = CLK_TOP_APLL12_DIV_TDM,
> +		.div_pdn_reg = CLK_AUDDIV_0,
> +		.div_pdn_mask_sft = APLL12_DIV_TDM_PDN_MASK_SFT,
> +		.div_reg = CLK_AUDDIV_3,
> +		.div_mask_sft = APLL12_CK_DIV_TDM_MASK_SFT,
> +		.div_mask = APLL12_CK_DIV_TDM_MASK,
> +		.div_sft = APLL12_CK_DIV_TDM_SFT,
> +		.div_apll_sel_reg = CLK_AUDDIV_0,
> +		.div_apll_sel_mask_sft = APLL_TDM_MCK_SEL_MASK_SFT,
> +		.div_apll_sel_sft = APLL_TDM_MCK_SEL_SFT,
> +	},
> +};
> +
> +int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int apll = mt8186_get_apll_by_rate(afe, rate);
> +	int apll_clk_id = apll == MT8186_APLL1 ?
> +			  CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;
> +	int m_sel_id = mck_div[mck_id].m_sel_id;
> +	int div_clk_id = mck_div[mck_id].div_clk_id;
> +	int ret;
> +
> +	/* select apll */
> +	if (m_sel_id >= 0) {
> +		ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
> +				 __func__, aud_clks[m_sel_id], ret);

dev_err()

> +			return ret;
> +		}
> +		ret = clk_set_parent(afe_priv->clk[m_sel_id],
> +				     afe_priv->clk[apll_clk_id]);
> +		if (ret) {
> +			dev_info(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
> +				 __func__, aud_clks[m_sel_id],
> +				aud_clks[apll_clk_id], ret);

again

> +			return ret;
> +		}
> +	}
> +
> +	/* enable div, set rate */
> +	ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);
> +	if (ret) {
> +		dev_info(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
> +			 __func__, aud_clks[div_clk_id], ret);

again

> +		return ret;
> +	}
> +	ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);
> +	if (ret) {
> +		dev_info(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n",
> +			 __func__, aud_clks[div_clk_id],
> +			 rate, ret);

again - and this fits in two lines.

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int m_sel_id = mck_div[mck_id].m_sel_id;
> +	int div_clk_id = mck_div[mck_id].div_clk_id;
> +
> +	clk_disable_unprepare(afe_priv->clk[div_clk_id]);
> +	if (m_sel_id >= 0)
> +		clk_disable_unprepare(afe_priv->clk[m_sel_id]);
> +}
> +
> +int mt8186_init_clock(struct mtk_base_afe *afe)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct device_node *of_node = afe->dev->of_node;
> +	int i = 0;
> +
> +	 mt8186_audsys_clk_register(afe);

Fix indentation please

> +
> +	afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
> +				     GFP_KERNEL);
> +	if (!afe_priv->clk)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < CLK_NUM; i++) {
> +		afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
> +		if (IS_ERR(afe_priv->clk[i])) {
> +			dev_info(afe->dev, "%s devm_clk_get %s fail, ret %ld\n",
> +				 __func__,
> +				 aud_clks[i], PTR_ERR(afe_priv->clk[i]));
> +			afe_priv->clk[i] = NULL;
> +		}
> +	}
> +
> +	afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node,
> +							       "mediatek,apmixedsys");
> +	if (IS_ERR(afe_priv->apmixedsys)) {
> +		dev_err(afe->dev, "%s() Cannot find apmixedsys controller: %ld\n",
> +			__func__, PTR_ERR(afe_priv->apmixedsys));
> +		return PTR_ERR(afe_priv->apmixedsys);
> +	}
> +
> +	afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node,
> +							     "mediatek,topckgen");
> +	if (IS_ERR(afe_priv->topckgen)) {
> +		dev_err(afe->dev, "%s() Cannot find topckgen controller: %ld\n",
> +			__func__, PTR_ERR(afe_priv->topckgen));
> +		return PTR_ERR(afe_priv->topckgen);
> +	}
> +
> +	afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node,
> +							     "mediatek,infracfg");
> +	if (IS_ERR(afe_priv->infracfg)) {
> +		dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n",
> +			__func__, PTR_ERR(afe_priv->infracfg));
> +		return PTR_ERR(afe_priv->infracfg);
> +	}
> +
> +	return 0;
> +}
> +
> +void mt8186_deinit_clock(struct mtk_base_afe *afe)
> +{
> +	mt8186_audsys_clk_unregister(afe);
> +}
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> new file mode 100644
> index 000000000000..3ce7a9a24d4a
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> @@ -0,0 +1,210 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * mt8186-afe-clk.h  --  Mediatek 8186 afe clock ctrl definition
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> + */
> +
> +#ifndef _MT8186_AFE_CLOCK_CTRL_H_
> +#define _MT8186_AFE_CLOCK_CTRL_H_
> +
> +#define PERI_BUS_DCM_CTRL 0x0074
> +#define MODULE_SW_CG_1_STA 0x0094
> +#define MODULE_SW_CG_2_STA 0x00ac
> +#define CLK_CFG_7 0x0080
> +#define CLK_CFG_8 0x0090
> +#define CLK_CFG_11 0x00c0
> +#define CLK_CFG_12 0x00d0
> +#define CLK_CFG_13 0x00e0
> +#define CLK_CFG_15 0x0100
> +#define AP_PLL_CON3 0x0014
> +#define APLL1_CON4 0x0328
> +#define APLL1_TUNER_CON0 0x0040
> +#define APLL2_CON4 0x033c
> +#define APLL2_TUNER_CON0 0x0044
> +
> +#define AP_PLL_CON5 0x0014
> +#define APLL1_CON0 0x02c0
> +#define APLL1_CON1 0x02c4
> +#define APLL1_CON2 0x02c8
> +#define APLL1_CON3 0x02cc
> +#define APLL1_PWR_CON0 0x02d0
> +
> +#define APLL2_CON0 0x02d4
> +#define APLL2_CON1 0x02d8
> +#define APLL2_CON2 0x02dc
> +#define APLL2_CON3 0x02e0
> +#define APLL2_PWR_CON0 0x02e4
> +
> +#define APMIXEDSYS_MAX_LENGTH APLL2_PWR_CON0
> +
> +#define CLK_CFG_6 0x0080
> +#define CLK_AUDDIV_0 0x0320
> +#define CLK_AUDDIV_1 0x0324
> +#define CLK_AUDDIV_2 0x0328
> +#define CKSYS_AUD_TOP_CFG 0x032c
> +#define CKSYS_AUD_TOP_MON 0x0330
> +#define CLK_AUDDIV_3 0x0334
> +
> +#define CLK_MAX_LENGTH CLK_AUDDIV_3
> +
> +/* CLK_CFG_6 */
> +#define CLK_AUD_INTBUS_SEL_SFT              16
> +#define CLK_AUD_INTBUS_SEL_MASK             0x3
> +#define CLK_AUD_INTBUS_SEL_MASK_SFT         (0x3 << 16)

#define CLK_AUD_INTBUS_SEL_MASK_SFT		GENMASK(23, 22)

> +
> +/* CLK_AUDDIV_0 */
> +#define APLL12_DIV0_PDN_SFT                0
> +#define APLL12_DIV0_PDN_MASK               0x1
> +#define APLL12_DIV0_PDN_MASK_SFT           (0x1 << 0)

BIT() macro please

#define APLL12_DIV0_PDN_MASK_SFT		BIT(0)

also, using tabulations instead of spaces is nicer.

> +#define APLL12_DIV1_PDN_SFT                1
> +#define APLL12_DIV1_PDN_MASK               0x1
> +#define APLL12_DIV1_PDN_MASK_SFT           (0x1 << 1)

Of course, BIT() macro again, here and everywhere else applicable.

> +#define APLL12_DIV2_PDN_SFT                2
> +#define APLL12_DIV2_PDN_MASK               0x1
> +#define APLL12_DIV2_PDN_MASK_SFT           (0x1 << 2)
> +#define APLL12_DIV4_PDN_SFT                3
> +#define APLL12_DIV4_PDN_MASK               0x1
> +#define APLL12_DIV4_PDN_MASK_SFT           (0x1 << 3)
> +#define APLL12_DIV_TDM_PDN_SFT             4
> +#define APLL12_DIV_TDM_PDN_MASK            0x1
> +#define APLL12_DIV_TDM_PDN_MASK_SFT        (0x1 << 4)
> +#define APLL_I2S0_MCK_SEL_SFT              16
> +#define APLL_I2S0_MCK_SEL_MASK             0x1
> +#define APLL_I2S0_MCK_SEL_MASK_SFT         (0x1 << 16)
> +#define APLL_I2S1_MCK_SEL_SFT              17
> +#define APLL_I2S1_MCK_SEL_MASK             0x1
> +#define APLL_I2S1_MCK_SEL_MASK_SFT         (0x1 << 17)
> +#define APLL_I2S2_MCK_SEL_SFT              18
> +#define APLL_I2S2_MCK_SEL_MASK             0x1
> +#define APLL_I2S2_MCK_SEL_MASK_SFT         (0x1 << 17)
> +#define APLL_I2S4_MCK_SEL_SFT              19
> +#define APLL_I2S4_MCK_SEL_MASK             0x1
> +#define APLL_I2S4_MCK_SEL_MASK_SFT         (0x1 << 19)
> +#define APLL_TDM_MCK_SEL_SFT               20
> +#define APLL_TDM_MCK_SEL_MASK              0x1
> +#define APLL_TDM_MCK_SEL_MASK_SFT          (0x1 << 20)
> +
> +/* CLK_AUDDIV_2 */
> +#define APLL12_CK_DIV0_SFT                 0
> +#define APLL12_CK_DIV0_MASK                0xff
> +#define APLL12_CK_DIV0_MASK_SFT            (0xff << 0)

GENMASK(7, 0)

> +#define APLL12_CK_DIV1_SFT                 8
> +#define APLL12_CK_DIV1_MASK                0xff
> +#define APLL12_CK_DIV1_MASK_SFT            (0xff << 8)

GENMASK(15, 8)

> +#define APLL12_CK_DIV2_SFT                 16
> +#define APLL12_CK_DIV2_MASK                0xff
> +#define APLL12_CK_DIV2_MASK_SFT            (0xff << 16)

Fix all the others too :))

> +#define APLL12_CK_DIV4_SFT                 24
> +#define APLL12_CK_DIV4_MASK                0xff
> +#define APLL12_CK_DIV4_MASK_SFT            (0xff << 24)
> +
> +/* CLK_AUDDIV_3 */
> +#define APLL12_CK_DIV_TDM_SFT              0
> +#define APLL12_CK_DIV_TDM_MASK             0xff
> +#define APLL12_CK_DIV_TDM_MASK_SFT         (0xff << 0)
> +
> +/* AUD_TOP_CFG */
> +#define AUD_TOP_CFG_SFT                    0
> +#define AUD_TOP_CFG_MASK                   0xffffffff
> +#define AUD_TOP_CFG_MASK_SFT               (0xffffffff << 0)

This is GENMASK(31, 0) for both MASK and MASK_SFT

> +
> +/* AUD_TOP_MON */
> +#define AUD_TOP_MON_SFT                    0
> +#define AUD_TOP_MON_MASK                   0xffffffff
> +#define AUD_TOP_MON_MASK_SFT               (0xffffffff << 0)

same here



Regards,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #9
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch adds mt8186 src dai driver
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-dai-src.c | 758 +++++++++++++++++++++
>   1 file changed, 758 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-src.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-src.c b/sound/soc/mediatek/mt8186/mt8186-dai-src.c
> new file mode 100644
> index 000000000000..7ff1623b591a
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-src.c
> @@ -0,0 +1,758 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +//  MediaTek ALSA SoC Audio DAI SRC Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/regmap.h>
> +#include "mt8186-afe-common.h"
> +#include "mt8186-interconnection.h"
> +
> +struct mtk_afe_src_priv {
> +	int dl_rate;
> +	int ul_rate;
> +};
> +
> +static const unsigned int src_iir_coeff_32_to_16[] = {
> +	0x0dbae6, 0xff9b0a, 0x0dbae6, 0x05e488, 0xe072b9, 0x000002,
> +	0x0dbae6, 0x000f3b, 0x0dbae6, 0x06a537, 0xe17d79, 0x000002,
> +	0x0dbae6, 0x01246a, 0x0dbae6, 0x087261, 0xe306be, 0x000002,
> +	0x0dbae6, 0x03437d, 0x0dbae6, 0x0bc16f, 0xe57c87, 0x000002,
> +	0x0dbae6, 0x072981, 0x0dbae6, 0x111dd3, 0xe94f2a, 0x000002,
> +	0x0dbae6, 0x0dc4a6, 0x0dbae6, 0x188611, 0xee85a0, 0x000002,
> +	0x0dbae6, 0x168b9a, 0x0dbae6, 0x200e8f, 0xf3ccf1, 0x000002,
> +	0x000000, 0x1b75cb, 0x1b75cb, 0x2374a2, 0x000000, 0x000001
> +};
> +
> +static const unsigned int src_iir_coeff_44_to_16[] = {
> +	0x09ae28, 0xf7d97d, 0x09ae28, 0x212a3d, 0xe0ac3a, 0x000002,
> +	0x09ae28, 0xf8525a, 0x09ae28, 0x216d72, 0xe234be, 0x000002,
> +	0x09ae28, 0xf980f5, 0x09ae28, 0x22a057, 0xe45a81, 0x000002,
> +	0x09ae28, 0xfc0a08, 0x09ae28, 0x24d3bd, 0xe7752d, 0x000002,
> +	0x09ae28, 0x016162, 0x09ae28, 0x27da01, 0xeb6ea8, 0x000002,
> +	0x09ae28, 0x0b67df, 0x09ae28, 0x2aca4a, 0xef34c4, 0x000002,
> +	0x000000, 0x135c50, 0x135c50, 0x2c1079, 0x000000, 0x000001
> +};
> +
> +static const unsigned int src_iir_coeff_44_to_32[] = {
> +	0x096966, 0x0c4d35, 0x096966, 0xedee81, 0xf05070, 0x000003,
> +	0x12d2cc, 0x193910, 0x12d2cc, 0xddbf4f, 0xe21e1d, 0x000002,
> +	0x12d2cc, 0x1a9e60, 0x12d2cc, 0xe18916, 0xe470fd, 0x000002,
> +	0x12d2cc, 0x1d06e0, 0x12d2cc, 0xe8a4a6, 0xe87b24, 0x000002,
> +	0x12d2cc, 0x207578, 0x12d2cc, 0xf4fe62, 0xef5917, 0x000002,
> +	0x12d2cc, 0x24055f, 0x12d2cc, 0x05ee2b, 0xf8b502, 0x000002,
> +	0x000000, 0x25a599, 0x25a599, 0x0fabe2, 0x000000, 0x000001
> +};
> +
> +static const unsigned int src_iir_coeff_48_to_16[] = {
> +	0x0296a4, 0xfd69dd, 0x0296a4, 0x209439, 0xe01ff9, 0x000002,
> +	0x0f4ff3, 0xf0d6d4, 0x0f4ff3, 0x209bc9, 0xe076c3, 0x000002,
> +	0x0e8490, 0xf1fe63, 0x0e8490, 0x20cfd6, 0xe12124, 0x000002,
> +	0x14852f, 0xed794a, 0x14852f, 0x21503d, 0xe28b32, 0x000002,
> +	0x136222, 0xf17677, 0x136222, 0x225be1, 0xe56964, 0x000002,
> +	0x0a8d85, 0xfc4a97, 0x0a8d85, 0x24310c, 0xea6952, 0x000002,
> +	0x05eff5, 0x043455, 0x05eff5, 0x4ced8f, 0xe134d6, 0x000001,
> +	0x000000, 0x3aebe6, 0x3aebe6, 0x04f3b0, 0x000000, 0x000004
> +};
> +
> +static const unsigned int src_iir_coeff_48_to_32[] = {
> +	0x10c1b8, 0x10a7df, 0x10c1b8, 0xe7514e, 0xe0b41f, 0x000002,
> +	0x10c1b8, 0x116257, 0x10c1b8, 0xe9402f, 0xe25aaa, 0x000002,
> +	0x10c1b8, 0x130c89, 0x10c1b8, 0xed3cc3, 0xe4dddb, 0x000002,
> +	0x10c1b8, 0x1600dd, 0x10c1b8, 0xf48000, 0xe90c55, 0x000002,
> +	0x10c1b8, 0x1a672e, 0x10c1b8, 0x00494c, 0xefa807, 0x000002,
> +	0x10c1b8, 0x1f38e6, 0x10c1b8, 0x0ee076, 0xf7c5f3, 0x000002,
> +	0x000000, 0x218370, 0x218370, 0x168b40, 0x000000, 0x000001
> +};
> +
> +static const unsigned int src_iir_coeff_48_to_44[] = {
> +	0x0bf71c, 0x170f3f, 0x0bf71c, 0xe3a4c8, 0xf096cb, 0x000003,
> +	0x0bf71c, 0x17395e, 0x0bf71c, 0xe58085, 0xf210c8, 0x000003,
> +	0x0bf71c, 0x1782bd, 0x0bf71c, 0xe95ef6, 0xf4c899, 0x000003,
> +	0x0bf71c, 0x17cd97, 0x0bf71c, 0xf1608a, 0xfa3b18, 0x000003,
> +	0x000000, 0x2fdc6f, 0x2fdc6f, 0xf15663, 0x000000, 0x000001
> +};
> +
> +static const unsigned int src_iir_coeff_96_to_16[] = {
> +	0x0805a1, 0xf21ae3, 0x0805a1, 0x3840bb, 0xe02a2e, 0x000002,
> +	0x0d5dd8, 0xe8f259, 0x0d5dd8, 0x1c0af6, 0xf04700, 0x000003,
> +	0x0bb422, 0xec08d9, 0x0bb422, 0x1bfccc, 0xf09216, 0x000003,
> +	0x08fde6, 0xf108be, 0x08fde6, 0x1bf096, 0xf10ae0, 0x000003,
> +	0x0ae311, 0xeeeda3, 0x0ae311, 0x37c646, 0xe385f5, 0x000002,
> +	0x044089, 0xfa7242, 0x044089, 0x37a785, 0xe56526, 0x000002,
> +	0x00c75c, 0xffb947, 0x00c75c, 0x378ba3, 0xe72c5f, 0x000002,
> +	0x000000, 0x0ef76e, 0x0ef76e, 0x377fda, 0x000000, 0x000001,
> +};
> +
> +static const unsigned int src_iir_coeff_96_to_44[] = {
> +	0x08b543, 0xfd80f4, 0x08b543, 0x0e2332, 0xe06ed0, 0x000002,
> +	0x1b6038, 0xf90e7e, 0x1b6038, 0x0ec1ac, 0xe16f66, 0x000002,
> +	0x188478, 0xfbb921, 0x188478, 0x105859, 0xe2e596, 0x000002,
> +	0x13eff3, 0xffa707, 0x13eff3, 0x13455c, 0xe533b7, 0x000002,
> +	0x0dc239, 0x03d458, 0x0dc239, 0x17f120, 0xe8b617, 0x000002,
> +	0x0745f1, 0x05d790, 0x0745f1, 0x1e3d75, 0xed5f18, 0x000002,
> +	0x05641f, 0x085e2b, 0x05641f, 0x48efd0, 0xe3e9c8, 0x000001,
> +	0x000000, 0x28f632, 0x28f632, 0x273905, 0x000000, 0x000001,
> +};
> +
> +static unsigned int mtk_get_src_freq_mode(struct mtk_base_afe *afe, int rate)
> +{
> +	switch (rate) {
> +	case 8000:
> +		return 0x00050000;

No leading zeroes please

> +	case 11025:
> +		return 0x0006E400;
> +	case 12000:
> +		return 0x00078000;
> +	case 16000:
> +		return 0x000A0000;
> +	case 22050:
> +		return 0x000DC800;
> +	case 24000:
> +		return 0x000F0000;
> +	case 32000:
> +		return 0x00140000;
> +	case 44100:
> +		return 0x001B9000;
> +	case 48000:
> +		return 0x001E0000;
> +	case 88200:
> +		return 0x00372000;
> +	case 96000:
> +		return 0x003C0000;
> +	case 176400:
> +		return 0x006E4000;
> +	case 192000:
> +		return 0x00780000;
> +	default:
> +		dev_info(afe->dev, "%s(), rate %d invalid!!!\n",
> +			 __func__, rate);

dev_err()

> +		return 0;
> +	}
> +}
> +
> +static const unsigned int *get_iir_coeff(unsigned int rate_in,
> +					 unsigned int rate_out,
> +					 unsigned int *param_num)
> +{
> +	if (rate_in == 32000 && rate_out == 16000) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_32_to_16);
> +		return src_iir_coeff_32_to_16;
> +	} else if (rate_in == 44100 && rate_out == 16000) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_44_to_16);
> +		return src_iir_coeff_44_to_16;
> +	} else if (rate_in == 44100 && rate_out == 32000) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_44_to_32);
> +		return src_iir_coeff_44_to_32;
> +	} else if ((rate_in == 48000 && rate_out == 16000) ||
> +		   (rate_in == 96000 && rate_out == 32000)) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_48_to_16);
> +		return src_iir_coeff_48_to_16;
> +	} else if (rate_in == 48000 && rate_out == 32000) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_48_to_32);
> +		return src_iir_coeff_48_to_32;
> +	} else if (rate_in == 48000 && rate_out == 44100) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_48_to_44);
> +		return src_iir_coeff_48_to_44;
> +	} else if (rate_in == 96000 && rate_out == 16000) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_96_to_16);
> +		return src_iir_coeff_96_to_16;
> +	} else if ((rate_in == 96000 && rate_out == 44100) ||
> +		   (rate_in == 48000 && rate_out == 22050)) {
> +		*param_num = ARRAY_SIZE(src_iir_coeff_96_to_44);
> +		return src_iir_coeff_96_to_44;
> +	}
> +
> +	*param_num = 0;
> +	return NULL;
> +}
> +
> +#define DEBUG_COEFF
> +static int mtk_set_src_1_param(struct mtk_base_afe *afe, int id)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
> +	unsigned int iir_coeff_num;
> +	unsigned int iir_stage;
> +	int rate_in = src_priv->dl_rate;
> +	int rate_out = src_priv->ul_rate;
> +	unsigned int out_freq_mode = mtk_get_src_freq_mode(afe,
> +							   rate_out);

Fits in one line.

> +	unsigned int in_freq_mode = mtk_get_src_freq_mode(afe,
> +							  rate_in);

ditto.

> +
> +	/* set out freq mode */
> +	regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3,
> +			   G_SRC_ASM_FREQ_4_MASK_SFT,
> +			   out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
> +
> +	/* set in freq mode */
> +	regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4,
> +			   G_SRC_ASM_FREQ_5_MASK_SFT,
> +			   in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
> +



> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL1_ASRC_2CH_CON5, 0x003f5986);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL1_ASRC_2CH_CON5, 0x003f5987);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL1_ASRC_2CH_CON6, 0x00001fbd);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL1_ASRC_2CH_CON2, 0x00000000);

All single ones of these fit in a single line.

> +
> +	/* set iir if in_rate > out_rate */
> +	if (rate_in > rate_out) {
> +		int i;
> +#ifdef DEBUG_COEFF
> +		int reg_val;
> +#endif
> +		const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
> +							      &iir_coeff_num);
> +
> +		if (iir_coeff_num == 0 || !iir_coeff) {
> +			dev_info(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
> +				 __func__, iir_coeff_num, iir_coeff);
> +			return -EINVAL;
> +		}
> +
> +		/* COEFF_SRAM_CTRL */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
> +				   G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
> +				   0x1 << G_SRC_COEFF_SRAM_CTRL_SFT);
> +		/* Clear coeff history to r/w coeff from the first position */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,
> +				   G_SRC_COEFF_SRAM_ADR_MASK_SFT,
> +				   0x0);
> +		/* Write SRC coeff, should not read the reg during write */
> +		for (i = 0; i < iir_coeff_num; i++)
> +			regmap_write(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,
> +				     iir_coeff[i]);
> +
> +#ifdef DEBUG_COEFF
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13,
> +				   G_SRC_COEFF_SRAM_ADR_MASK_SFT,
> +				   0x0);
> +
> +		for (i = 0; i < iir_coeff_num; i++) {
> +			regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12,
> +				    &reg_val);
> +			dev_info(afe->dev, "%s(), i = %d, coeff = 0x%x\n",
> +				 __func__, i, reg_val);
> +		}
> +#endif
> +		/* disable sram access */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0,
> +				   G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
> +				   0x0);
> +		/* CHSET_IIR_STAGE */
> +		iir_stage = (iir_coeff_num / 6) - 1;
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_STAGE_MASK_SFT,
> +				   iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
> +		/* CHSET_IIR_EN */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_EN_MASK_SFT,
> +				   0x1 << G_SRC_CHSET_IIR_EN_SFT);

BIT()

> +	} else {
> +		/* CHSET_IIR_EN off */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_EN_MASK_SFT,
> +				   0x0);
> +	}
> +
> +	return 0;
> +}
> +
> +static int mtk_set_src_2_param(struct mtk_base_afe *afe, int id)
> +{
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
> +	unsigned int iir_coeff_num;
> +	unsigned int iir_stage;
> +	int rate_in = src_priv->dl_rate;
> +	int rate_out = src_priv->ul_rate;
> +	unsigned int out_freq_mode = mtk_get_src_freq_mode(afe,
> +							   rate_out);
> +	unsigned int in_freq_mode = mtk_get_src_freq_mode(afe,
> +							  rate_in);
> +
> +	/* set out freq mode */
> +	regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3,
> +			   G_SRC_ASM_FREQ_4_MASK_SFT,
> +			   out_freq_mode << G_SRC_ASM_FREQ_4_SFT);
> +
> +	/* set in freq mode */
> +	regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4,
> +			   G_SRC_ASM_FREQ_5_MASK_SFT,
> +			   in_freq_mode << G_SRC_ASM_FREQ_5_SFT);
> +
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL2_ASRC_2CH_CON5, 0x003f5986);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL2_ASRC_2CH_CON5, 0x003f5987);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL2_ASRC_2CH_CON6, 0x00001fbd);
> +	regmap_write(afe->regmap,
> +		     AFE_GENERAL2_ASRC_2CH_CON2, 0x00000000);

no leading zeros; fits in one line.

> +
> +	/* set iir if in_rate > out_rate */
> +	if (rate_in > rate_out) {
> +		int i;
> +#ifdef DEBUG_COEFF
> +		int reg_val;
> +#endif
> +		const unsigned int *iir_coeff = get_iir_coeff(rate_in, rate_out,
> +							      &iir_coeff_num);
> +
> +		if (iir_coeff_num == 0 || !iir_coeff) {
> +			dev_info(afe->dev, "%s(), iir coeff error, num %d, coeff %p\n",
> +				 __func__, iir_coeff_num, iir_coeff);

dev_err()

> +			return -EINVAL;
> +		}
> +
> +		/* COEFF_SRAM_CTRL */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
> +				   G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
> +				   0x1 << G_SRC_COEFF_SRAM_CTRL_SFT);

BIT()

> +		/* Clear coeff history to r/w coeff from the first position */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,
> +				   G_SRC_COEFF_SRAM_ADR_MASK_SFT,
> +				   0x0);
> +		/* Write SRC coeff, should not read the reg during write */
> +		for (i = 0; i < iir_coeff_num; i++)
> +			regmap_write(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,
> +				     iir_coeff[i]);
> +
> +#ifdef DEBUG_COEFF
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13,
> +				   G_SRC_COEFF_SRAM_ADR_MASK_SFT,
> +				   0x0);
> +
> +		for (i = 0; i < iir_coeff_num; i++) {
> +			regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12,
> +				    &reg_val);
> +			dev_info(afe->dev, "%s(), i = %d, coeff = 0x%x\n",
> +				 __func__, i, reg_val);
> +		}
> +#endif
> +		/* disable sram access */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0,
> +				   G_SRC_COEFF_SRAM_CTRL_MASK_SFT,
> +				   0x0);
> +		/* CHSET_IIR_STAGE */
> +		iir_stage = (iir_coeff_num / 6) - 1;
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_STAGE_MASK_SFT,
> +				   iir_stage << G_SRC_CHSET_IIR_STAGE_SFT);
> +		/* CHSET_IIR_EN */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_EN_MASK_SFT,
> +				   0x1 << G_SRC_CHSET_IIR_EN_SFT);
> +	} else {
> +		/* CHSET_IIR_EN off */
> +		regmap_update_bits(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2,
> +				   G_SRC_CHSET_IIR_EN_MASK_SFT, 0x0);
> +	}
> +
> +	return 0;
> +}
> +
> +#define HW_SRC_1_EN_W_NAME "HW_SRC_1_Enable"
> +#define HW_SRC_2_EN_W_NAME "HW_SRC_2_Enable"
> +
> +static int mtk_hw_src_event(struct snd_soc_dapm_widget *w,
> +			    struct snd_kcontrol *kcontrol,
> +			    int event)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int id;
> +	struct mtk_afe_src_priv *src_priv;
> +	unsigned int reg;
> +
> +	if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
> +		id = MT8186_DAI_SRC_1;
> +	else
> +		id = MT8186_DAI_SRC_2;
> +
> +	src_priv = afe_priv->dai_priv[id];
> +
> +	dev_dbg(afe->dev, "%s(), name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",
> +		__func__,
> +		w->name, event,
> +		id, src_priv,
> +		src_priv->dl_rate,
> +		src_priv->ul_rate);
	dev_dbg(afe->dev,

		"%s: name %s, event 0x%x, id %d, src_priv %p, dl_rate %d, ul_rate %d\n",

		__func__, w->name, event, id, src_priv,

		src_priv->dl_rate, src_priv->ul_rate);

> +
> +	switch (event) {
> +	case SND_SOC_DAPM_PRE_PMU:
> +		if (id == MT8186_DAI_SRC_1)
> +			mtk_set_src_1_param(afe, id);
> +		else
> +			mtk_set_src_2_param(afe, id);
> +		break;
> +	case SND_SOC_DAPM_POST_PMU:
> +		reg = (id == MT8186_DAI_SRC_1) ?
> +		      AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
> +		/* ASM_ON */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_ASM_ON_MASK_SFT,
> +				   0x1 << G_SRC_ASM_ON_SFT);

BIT()

> +		/* CHSET_ON */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_CHSET_ON_MASK_SFT,
> +				   0x1 << G_SRC_CHSET_ON_SFT);

same

> +		/* CHSET_STR_CLR */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_CHSET_STR_CLR_MASK_SFT,
> +				   0x1 << G_SRC_CHSET_STR_CLR_SFT);

again

> +		break;
> +	case SND_SOC_DAPM_PRE_PMD:
> +		reg = (id == MT8186_DAI_SRC_1) ?
> +		      AFE_GENERAL1_ASRC_2CH_CON0 : AFE_GENERAL2_ASRC_2CH_CON0;
> +		/* ASM_OFF */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_ASM_ON_MASK_SFT, 0x0);

Fits in one line

> +		/* CHSET_OFF */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_CHSET_ON_MASK_SFT, 0x0);
> +		/* CHSET_STR_CLR */
> +		regmap_update_bits(afe->regmap, reg,
> +				   G_SRC_CHSET_STR_CLR_MASK_SFT, 0x0);
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	return 0;
> +}
> +

..snip..

> +
> +static int mtk_afe_src_en_connect(struct snd_soc_dapm_widget *source,
> +				  struct snd_soc_dapm_widget *sink)
> +{
> +	struct snd_soc_dapm_widget *w = source;
> +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct mtk_afe_src_priv *src_priv;
> +
> +	if (strcmp(w->name, HW_SRC_1_EN_W_NAME) == 0)
> +		src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_1];
> +	else
> +		src_priv = afe_priv->dai_priv[MT8186_DAI_SRC_2];
> +
> +	dev_info(afe->dev,
> +		 "%s(), source %s, sink %s, dl_rate %d, ul_rate %d\n",
> +		 __func__, source->name, sink->name,
> +		 src_priv->dl_rate, src_priv->ul_rate);

dev_dbg()

> +
> +	return (src_priv->dl_rate > 0 && src_priv->ul_rate > 0) ? 1 : 0;
> +}
> +
> +static const struct snd_soc_dapm_route mtk_dai_src_routes[] = {
> +	{"HW_SRC_1_IN_CH1", "DL1_CH1 Switch", "DL1"},
> +	{"HW_SRC_1_IN_CH2", "DL1_CH2 Switch", "DL1"},
> +	{"HW_SRC_2_IN_CH1", "DL1_CH1 Switch", "DL1"},
> +	{"HW_SRC_2_IN_CH2", "DL1_CH2 Switch", "DL1"},
> +	{"HW_SRC_1_IN_CH1", "DL2_CH1 Switch", "DL2"},
> +	{"HW_SRC_1_IN_CH2", "DL2_CH2 Switch", "DL2"},
> +	{"HW_SRC_2_IN_CH1", "DL2_CH1 Switch", "DL2"},
> +	{"HW_SRC_2_IN_CH2", "DL2_CH2 Switch", "DL2"},
> +	{"HW_SRC_1_IN_CH1", "DL3_CH1 Switch", "DL3"},
> +	{"HW_SRC_1_IN_CH2", "DL3_CH2 Switch", "DL3"},
> +	{"HW_SRC_2_IN_CH1", "DL3_CH1 Switch", "DL3"},
> +	{"HW_SRC_2_IN_CH2", "DL3_CH2 Switch", "DL3"},
> +	{"HW_SRC_1_IN_CH1", "DL6_CH1 Switch", "DL6"},
> +	{"HW_SRC_1_IN_CH2", "DL6_CH2 Switch", "DL6"},
> +	{"HW_SRC_2_IN_CH1", "DL6_CH1 Switch", "DL6"},
> +	{"HW_SRC_2_IN_CH2", "DL6_CH2 Switch", "DL6"},
> +	{"HW_SRC_1_IN_CH1", "DL5_CH1 Switch", "DL5"},
> +	{"HW_SRC_1_IN_CH2", "DL5_CH2 Switch", "DL5"},
> +	{"HW_SRC_2_IN_CH1", "DL5_CH1 Switch", "DL5"},
> +	{"HW_SRC_2_IN_CH2", "DL5_CH2 Switch", "DL5"},
> +	{"HW_SRC_1_IN_CH1", "DL4_CH1 Switch", "DL4"},
> +	{"HW_SRC_1_IN_CH2", "DL4_CH2 Switch", "DL4"},
> +	{"HW_SRC_2_IN_CH1", "DL4_CH1 Switch", "DL4"},
> +	{"HW_SRC_2_IN_CH2", "DL4_CH2 Switch", "DL4"},
> +
> +	{"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH1"},
> +	{"HW_SRC_1_In", NULL, "HW_SRC_1_IN_CH2"},
> +
> +	{"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH1"},
> +	{"HW_SRC_2_In", NULL, "HW_SRC_2_IN_CH2"},
> +
> +	{"HW_SRC_1_In", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
> +	{"HW_SRC_1_Out", NULL, HW_SRC_1_EN_W_NAME, mtk_afe_src_en_connect},
> +	{"HW_SRC_2_In", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
> +	{"HW_SRC_2_Out", NULL, HW_SRC_2_EN_W_NAME, mtk_afe_src_en_connect},
> +
> +	{"HW SRC 1 In Endpoint", NULL, "HW_SRC_1_In"},
> +	{"HW SRC 2 In Endpoint", NULL, "HW_SRC_2_In"},
> +	{"HW_SRC_1_Out", NULL, "HW SRC 1 Out Endpoint"},
> +	{"HW_SRC_2_Out", NULL, "HW SRC 2 Out Endpoint"},
> +};
> +
> +/* dai ops */
> +static int mtk_dai_src_hw_params(struct snd_pcm_substream *substream,
> +				 struct snd_pcm_hw_params *params,
> +				 struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int id = dai->id;
> +	struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
> +	unsigned int sft, mask;
> +	unsigned int rate = params_rate(params);
> +	unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate, id);
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> +		 __func__,
> +		 id,
> +		 substream->stream,
> +		 rate);

Fits in two lines.

> +
> +	/* rate */
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> +		src_priv->dl_rate = rate;
> +		if (id == MT8186_DAI_SRC_1) {
> +			sft = GENERAL1_ASRCIN_MODE_SFT;
> +			mask = GENERAL1_ASRCIN_MODE_MASK;
> +		} else {
> +			sft = GENERAL2_ASRCIN_MODE_SFT;
> +			mask = GENERAL2_ASRCIN_MODE_MASK;
> +		}
> +	} else {
> +		src_priv->ul_rate = rate;
> +		if (id == MT8186_DAI_SRC_1) {
> +			sft = GENERAL1_ASRCOUT_MODE_SFT;
> +			mask = GENERAL1_ASRCOUT_MODE_MASK;
> +		} else {
> +			sft = GENERAL2_ASRCOUT_MODE_SFT;
> +			mask = GENERAL2_ASRCOUT_MODE_MASK;
> +		}
> +	}
> +
> +	regmap_update_bits(afe->regmap,
> +			   GENERAL_ASRC_MODE,
> +			   mask << sft,
> +			   rate_reg << sft);

Fits in one line (90 col is borderline ok)

> +
> +	return 0;
> +}
> +
> +static int mtk_dai_src_hw_free(struct snd_pcm_substream *substream,
> +			       struct snd_soc_dai *dai)
> +{
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int id = dai->id;
> +	struct mtk_afe_src_priv *src_priv = afe_priv->dai_priv[id];
> +
> +	dev_info(afe->dev, "%s(), id %d, stream %d\n",
> +		 __func__,
> +		 id,
> +		 substream->stream);

dev_dbg(), fits in two lines.

> +
> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
> +		src_priv->dl_rate = 0;
> +	else
> +		src_priv->ul_rate = 0;
> +
> +	return 0;
> +}
> +

Thanks,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #10
Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> This patch add gpio control for all audio interface separately.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/mt8186/mt8186-afe-gpio.c | 210 ++++++++++++++++++++
>   sound/soc/mediatek/mt8186/mt8186-afe-gpio.h |  19 ++
>   2 files changed, 229 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> new file mode 100644
> index 000000000000..6faec5c95bf3
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> @@ -0,0 +1,210 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// mt8186-afe-gpio.c  --  Mediatek 8186 afe gpio ctrl
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/gpio.h>
> +#include <linux/pinctrl/consumer.h>
> +
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-gpio.h"
> +
> +struct pinctrl *aud_pinctrl;
> +
> +enum mt8186_afe_gpio {
> +	MT8186_AFE_GPIO_CLK_MOSI_OFF,
> +	MT8186_AFE_GPIO_CLK_MOSI_ON,
> +	MT8186_AFE_GPIO_CLK_MISO_OFF,
> +	MT8186_AFE_GPIO_CLK_MISO_ON,
> +	MT8186_AFE_GPIO_DAT_MISO_OFF,
> +	MT8186_AFE_GPIO_DAT_MISO_ON,
> +	MT8186_AFE_GPIO_DAT_MOSI_OFF,
> +	MT8186_AFE_GPIO_DAT_MOSI_ON,
> +	MT8186_AFE_GPIO_I2S0_OFF,
> +	MT8186_AFE_GPIO_I2S0_ON,
> +	MT8186_AFE_GPIO_I2S1_OFF,
> +	MT8186_AFE_GPIO_I2S1_ON,
> +	MT8186_AFE_GPIO_I2S2_OFF,
> +	MT8186_AFE_GPIO_I2S2_ON,
> +	MT8186_AFE_GPIO_I2S3_OFF,
> +	MT8186_AFE_GPIO_I2S3_ON,
> +	MT8186_AFE_GPIO_TDM_OFF,
> +	MT8186_AFE_GPIO_TDM_ON,
> +	MT8186_AFE_GPIO_PCM_OFF,
> +	MT8186_AFE_GPIO_PCM_ON,
> +	MT8186_AFE_GPIO_GPIO_NUM
> +};
> +
> +struct audio_gpio_attr {
> +	const char *name;
> +	bool gpio_prepare;
> +	struct pinctrl_state *gpioctrl;
> +};
> +
> +static struct audio_gpio_attr aud_gpios[MT8186_AFE_GPIO_GPIO_NUM] = {
> +	[MT8186_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
> +	[MT8186_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
> +	[MT8186_AFE_GPIO_CLK_MISO_OFF] = {"aud_clk_miso_off", false, NULL},
> +	[MT8186_AFE_GPIO_CLK_MISO_ON] = {"aud_clk_miso_on", false, NULL},
> +	[MT8186_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
> +	[MT8186_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
> +	[MT8186_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
> +	[MT8186_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
> +	[MT8186_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
> +	[MT8186_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
> +	[MT8186_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
> +	[MT8186_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
> +	[MT8186_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
> +	[MT8186_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
> +	[MT8186_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
> +	[MT8186_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
> +	[MT8186_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
> +	[MT8186_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
> +	[MT8186_AFE_GPIO_PCM_OFF] = {"aud_gpio_pcm_off", false, NULL},
> +	[MT8186_AFE_GPIO_PCM_ON] = {"aud_gpio_pcm_on", false, NULL},
> +};
> +
> +static DEFINE_MUTEX(gpio_request_mutex);
> +
> +int mt8186_afe_gpio_init(struct device *dev)
> +{
> +	int ret;
> +	int i = 0;
> +
> +	aud_pinctrl = devm_pinctrl_get(dev);
> +	if (IS_ERR(aud_pinctrl)) {
> +		ret = PTR_ERR(aud_pinctrl);
> +		dev_info(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
> +			 __func__, ret);

dev_err()
... and return ret.

> +		return -ENODEV;
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
> +		aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
> +							     aud_gpios[i].name);
> +		if (IS_ERR(aud_gpios[i].gpioctrl)) {
> +			ret = PTR_ERR(aud_gpios[i].gpioctrl);
> +			dev_info(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
> +				 __func__, aud_gpios[i].name, ret);

dev_err()

P.S.: I think that this function should return ret, at this point, to avoid
       unexpected behavior.


> +		} else {
> +			aud_gpios[i].gpio_prepare = true;
> +		}
> +	}
> +
> +	/* gpio status init */
> +	mt8186_afe_gpio_request(dev, false, MT8186_DAI_ADDA, 0);
> +	mt8186_afe_gpio_request(dev, false, MT8186_DAI_ADDA, 1);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(mt8186_afe_gpio_init);
> +
> +static int mt8186_afe_gpio_select(struct device *dev,
> +				  enum mt8186_afe_gpio type)
> +{
> +	int ret = 0;
> +
> +	if (type < 0 || type >= MT8186_AFE_GPIO_GPIO_NUM) {
> +		dev_info(dev, "%s(), error, invalid gpio type %d\n",
> +			 __func__, type);
> +		return -EINVAL;
> +	}
> +
> +	if (!aud_gpios[type].gpio_prepare) {
> +		dev_info(dev, "%s(), error, gpio type %d not prepared\n",
> +			 __func__, type);
> +		return -EIO;
> +	}
> +
> +	ret = pinctrl_select_state(aud_pinctrl,
> +				   aud_gpios[type].gpioctrl);
> +	if (ret)
> +		dev_info(dev, "%s(), error, can not set gpio type %d\n",
> +			 __func__, type);
> +
> +	return ret;

Please change it like so:

	if (ret) {
		dev_err(dev, "Failed to select picntrl state for type %d\n", type);
		return ret;
	}

	return 0;

> +}
> +
> +static int mt8186_afe_gpio_adda_dl(struct device *dev, bool enable)
> +{
> +	if (enable) {
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_ON);
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_ON);
> +	} else {
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MOSI_OFF);
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MOSI_OFF);
> +	}
> +
> +	return 0;
> +}
> +
> +static int mt8186_afe_gpio_adda_ul(struct device *dev, bool enable)
> +{
> +	if (enable) {
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_ON);
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_ON);
> +	} else {
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_DAT_MISO_OFF);
> +		mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_CLK_MISO_OFF);
> +	}
> +
> +	return 0;
> +}
> +
> +int mt8186_afe_gpio_request(struct device *dev, bool enable,
> +			    int dai, int uplink)
> +{

I think that it's more readable and even shorter if you do:

	enum mt8186_afe_gpio sel;

	int ret = -EINVAL;



	mutex_lock(&gpio_request_mutex);



	switch (dai) {

	case MT8186_DAI_ADDA:
		if (uplink)
			ret = mt8186_afe_gpio_adda_ul(dev, enable);
		else
			ret = mt8186_afe_gpio_adda_dl(dev, enable);
		goto unlock;
	case MT8186_DAI_I2S_0:

		sel = enable ? MT8186_AFE_GPIO_I2S0_ON : MT8186_AFE_GPIO_I2S0_OFF;

		break;

	case MT8186_DAI_I2S_1:

		sel = enable ? MT8186_AFE_GPIO_I2S1_ON : MT8186_AFE_GPIO_I2S1_OFF;

		break;



	.................... all other cases ................

	default:

		dev_err(dev, "invalid dai %d\n", dai);

		goto unlock;

	}


	ret = mt8186_afe_gpio_select(dev, sel);


unlock:

	mutex_unlock(&gpio_request_mutex);

	return ret;
}

> +	mutex_lock(&gpio_request_mutex);
> +	switch (dai) {
> +	case MT8186_DAI_ADDA:
> +		if (uplink)
> +			mt8186_afe_gpio_adda_ul(dev, enable);
> +		else
> +			mt8186_afe_gpio_adda_dl(dev, enable);
> +		break;
> +	case MT8186_DAI_I2S_0:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S0_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S0_OFF);
> +		break;
> +	case MT8186_DAI_I2S_1:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S1_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S1_OFF);
> +		break;
> +	case MT8186_DAI_I2S_2:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S2_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S2_OFF);
> +		break;
> +	case MT8186_DAI_I2S_3:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S3_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_I2S3_OFF);
> +		break;
> +	case MT8186_DAI_TDM_IN:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_TDM_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_TDM_OFF);
> +		break;
> +	case MT8186_DAI_PCM:
> +		if (enable)
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_PCM_ON);
> +		else
> +			mt8186_afe_gpio_select(dev, MT8186_AFE_GPIO_PCM_OFF);
> +		break;
> +	default:
> +		mutex_unlock(&gpio_request_mutex);
> +		dev_info(dev, "%s(), invalid dai %d\n", __func__, dai);
> +		return -EINVAL;
> +	}
> +	mutex_unlock(&gpio_request_mutex);
> +	return 0;
> +}
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> new file mode 100644
> index 000000000000..1ddc27838eb1
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * mt6833-afe-gpio.h  --  Mediatek 6833 afe gpio ctrl definition
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> + */
> +
> +#ifndef _MT8186_AFE_GPIO_H_
> +#define _MT8186_AFE_GPIO_H_
> +
> +struct mtk_base_afe;
> +
> +int mt8186_afe_gpio_init(struct device *dev);
> +
> +int mt8186_afe_gpio_request(struct device *dev, bool enable,
> +			    int dai, int uplink);
> +
> +#endif
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #11
Il 17/02/22 14:42, Jiaxin Yu ha scritto:
> This patch adds mt8186 platform and affiliated driver.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   sound/soc/mediatek/Kconfig                    |   44 +
>   sound/soc/mediatek/Makefile                   |    1 +
>   sound/soc/mediatek/mt8186/Makefile            |   21 +
>   sound/soc/mediatek/mt8186/mt8186-afe-common.h |  245 ++
>   .../soc/mediatek/mt8186/mt8186-afe-control.c  |  261 ++
>   sound/soc/mediatek/mt8186/mt8186-afe-pcm.c    | 3029 +++++++++++++++
>   .../mediatek/mt8186/mt8186-interconnection.h  |   69 +
>   .../soc/mediatek/mt8186/mt8186-misc-control.c | 1728 +++++++++
>   sound/soc/mediatek/mt8186/mt8186-reg.h        | 3433 +++++++++++++++++
>   9 files changed, 8831 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/Makefile
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-common.h
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-control.c
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-interconnection.h
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-misc-control.c
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-reg.h
> 
> diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
> index 3b1ddea26a9e..d3528bdbb00a 100644
> --- a/sound/soc/mediatek/Kconfig
> +++ b/sound/soc/mediatek/Kconfig
> @@ -152,6 +152,50 @@ config SND_SOC_MT8183_DA7219_MAX98357A
>   	  Select Y if you have such device.
>   	  If unsure select "N".
>   
> +config SND_SOC_MT8186
> +	tristate "ASoC support for Mediatek MT8186 chip"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on COMMON_CLK
> +	select SND_SOC_MEDIATEK
> +	select MFD_SYSCON if SND_SOC_MT6366
> +	help
> +	  This adds ASoC driver for Mediatek MT8186 boards
> +	  that can be used with other codecs.
> +	  Select Y if you have such device.
> +	  If unsure select "N".
> +
> +config SND_SOC_MT8186_MT6366_DA7219_MAX98357
> +	tristate "ASoC Audio driver for MT8186 with DA7219 MAX98357A codec"
> +	depends on I2C && GPIOLIB
> +	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
> +	select SND_SOC_MT6366
> +	select SND_SOC_MAX98357A
> +	select SND_SOC_DA7219
> +	select SND_SOC_BT_SCO
> +	select SND_SOC_DMIC
> +	select SND_SOC_HDMI_CODEC
> +	help
> +	  This adds ASoC driver for Mediatek MT8186 boards
> +	  with the MT6366 DA7219 MAX98357A codecs.
> +	  Select Y if you have such device.
> +	  If unsure select "N".
> +
> +config SND_SOC_MT8186_MT6366_RT1019_RT5682S
> +	tristate "ASoC Audio driver for MT8186 with RT1019 RT5682S codec"
> +	depends on I2C && GPIOLIB
> +	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
> +	select SND_SOC_MT6366
> +	select SND_SOC_RT1015P
> +	select SND_SOC_RT5682S
> +	select SND_SOC_BT_SCO
> +	select SND_SOC_DMIC
> +	select SND_SOC_HDMI_CODEC
> +	help
> +	  This adds ASoC driver for Mediatek MT8186 boards
> +	  with the MT6366 RT1019 RT5682S codecs.
> +	  Select Y if you have such device.
> +	  If unsure select "N".
> +
>   config SND_SOC_MTK_BTCVSD
>   	tristate "ALSA BT SCO CVSD/MSBC Driver"
>   	help
> diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
> index 34778ca12106..5571c640a288 100644
> --- a/sound/soc/mediatek/Makefile
> +++ b/sound/soc/mediatek/Makefile
> @@ -4,5 +4,6 @@ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
>   obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
>   obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
>   obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
> +obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
>   obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
>   obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
> diff --git a/sound/soc/mediatek/mt8186/Makefile b/sound/soc/mediatek/mt8186/Makefile
> new file mode 100644
> index 000000000000..9f3bead9cdf8
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/Makefile
> @@ -0,0 +1,21 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# platform driver
> +snd-soc-mt8186-afe-objs := \
> +	mt8186-afe-pcm.o \
> +	mt8186-audsys-clk.o \
> +	mt8186-afe-clk.o \
> +	mt8186-afe-gpio.o \
> +	mt8186-dai-adda.o \
> +	mt8186-afe-control.o \
> +	mt8186-dai-i2s.o \
> +	mt8186-dai-hw-gain.o \
> +	mt8186-dai-pcm.o \
> +	mt8186-dai-src.o \
> +	mt8186-dai-hostless.o \
> +	mt8186-dai-tdm.o \
> +	mt8186-misc-control.o
> +
> +obj-$(CONFIG_SND_SOC_MT8186) += snd-soc-mt8186-afe.o
> +obj-$(CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357) += mt8186-mt6366-da7219-max98357.o
> +obj-$(CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S) += mt8186-mt6366-rt1019-rt5682s.o
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-common.h b/sound/soc/mediatek/mt8186/mt8186-afe-common.h
> new file mode 100644
> index 000000000000..b2b50faa3887
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-common.h
> @@ -0,0 +1,245 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * mt8186-afe-common.h  --  Mediatek 8186 audio driver definitions
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> + */
> +
> +#ifndef _MT_8186_AFE_COMMON_H_
> +#define _MT_8186_AFE_COMMON_H_
> +#include <sound/soc.h>
> +#include <linux/list.h>
> +#include <linux/regmap.h>
> +#include "mt8186-reg.h"
> +#include "../common/mtk-base-afe.h"
> +
> +#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
> +#define AUDIO_AEE(message) \
> +	(aee_kernel_exception_api(__FILE__, \
> +				  __LINE__, \
> +				  DB_OPT_FTRACE, message, \
> +				  "audio assert"))
> +#else
> +#define AUDIO_AEE(message) WARN_ON(true)
> +#endif

There is no such AEE upstream, please remove this block entirely.

...snip...

> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-control.c b/sound/soc/mediatek/mt8186/mt8186-afe-control.c
> new file mode 100644
> index 000000000000..cb863716a74b
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-control.c
> @@ -0,0 +1,261 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include "mt8186-afe-common.h"
> +#include <linux/pm_runtime.h>
> +
> +enum {
> +	MTK_AFE_RATE_8K = 0,

You just need to define the first one as zero and you don't need to
assign numbers to the others, since they are sequential.
Please fix.

> +	MTK_AFE_RATE_11K = 1,
> +	MTK_AFE_RATE_12K = 2,
> +	MTK_AFE_RATE_384K = 3,
> +	MTK_AFE_RATE_16K = 4,
> +	MTK_AFE_RATE_22K = 5,
> +	MTK_AFE_RATE_24K = 6,
> +	MTK_AFE_RATE_352K = 7,
> +	MTK_AFE_RATE_32K = 8,
> +	MTK_AFE_RATE_44K = 9,
> +	MTK_AFE_RATE_48K = 10,
> +	MTK_AFE_RATE_88K = 11,
> +	MTK_AFE_RATE_96K = 12,
> +	MTK_AFE_RATE_176K = 13,
> +	MTK_AFE_RATE_192K = 14,
> +	MTK_AFE_RATE_260K = 15,
> +};
> +
> +enum {
> +	MTK_AFE_PCM_RATE_8K = 0,
> +	MTK_AFE_PCM_RATE_16K = 1,
> +	MTK_AFE_PCM_RATE_32K = 2,
> +	MTK_AFE_PCM_RATE_48K = 3,

same here

> +};
> +
> +enum {
> +	MTK_AFE_TDM_RATE_8K = 0,
> +	MTK_AFE_TDM_RATE_12K = 1,
> +	MTK_AFE_TDM_RATE_16K = 2,
> +	MTK_AFE_TDM_RATE_24K = 3,
> +	MTK_AFE_TDM_RATE_32K = 4,
> +	MTK_AFE_TDM_RATE_48K = 5,
> +	MTK_AFE_TDM_RATE_64K = 6,
> +	MTK_AFE_TDM_RATE_96K = 7,
> +	MTK_AFE_TDM_RATE_128K = 8,
> +	MTK_AFE_TDM_RATE_192K = 9,
> +	MTK_AFE_TDM_RATE_256K = 10,
> +	MTK_AFE_TDM_RATE_384K = 11,
> +	MTK_AFE_TDM_RATE_11K = 16,
> +	MTK_AFE_TDM_RATE_22K = 17,
> +	MTK_AFE_TDM_RATE_44K = 18,
> +	MTK_AFE_TDM_RATE_88K = 19,
> +	MTK_AFE_TDM_RATE_176K = 20,
> +	MTK_AFE_TDM_RATE_352K = 21, > +};
> +
> +enum {
> +	MTK_AFE_TDM_RELATCH_RATE_8K = 0,
> +	MTK_AFE_TDM_RELATCH_RATE_11K = 1,
> +	MTK_AFE_TDM_RELATCH_RATE_12K = 2,
> +	MTK_AFE_TDM_RELATCH_RATE_16K = 4,
> +	MTK_AFE_TDM_RELATCH_RATE_22K = 5,
> +	MTK_AFE_TDM_RELATCH_RATE_24K = 6,
> +	MTK_AFE_TDM_RELATCH_RATE_32K = 8,
> +	MTK_AFE_TDM_RELATCH_RATE_44K = 9,
> +	MTK_AFE_TDM_RELATCH_RATE_48K = 10,
> +	MTK_AFE_TDM_RELATCH_RATE_88K = 13,
> +	MTK_AFE_TDM_RELATCH_RATE_96K = 14,
> +	MTK_AFE_TDM_RELATCH_RATE_176K = 17,
> +	MTK_AFE_TDM_RELATCH_RATE_192K = 18,
> +	MTK_AFE_TDM_RELATCH_RATE_352K = 21,
> +	MTK_AFE_TDM_RELATCH_RATE_384K = 22,
> +};
> +
> +unsigned int mt8186_general_rate_transform(struct device *dev,
> +					   unsigned int rate)
> +{
> +	switch (rate) {
> +	case 8000:
> +		return MTK_AFE_RATE_8K;
> +	case 11025:
> +		return MTK_AFE_RATE_11K;
> +	case 12000:
> +		return MTK_AFE_RATE_12K;
> +	case 16000:
> +		return MTK_AFE_RATE_16K;
> +	case 22050:
> +		return MTK_AFE_RATE_22K;
> +	case 24000:
> +		return MTK_AFE_RATE_24K;
> +	case 32000:
> +		return MTK_AFE_RATE_32K;
> +	case 44100:
> +		return MTK_AFE_RATE_44K;
> +	case 48000:
> +		return MTK_AFE_RATE_48K;
> +	case 88200:
> +		return MTK_AFE_RATE_88K;
> +	case 96000:
> +		return MTK_AFE_RATE_96K;
> +	case 176400:
> +		return MTK_AFE_RATE_176K;
> +	case 192000:
> +		return MTK_AFE_RATE_192K;
> +	case 260000:
> +		return MTK_AFE_RATE_260K;
> +	case 352800:
> +		return MTK_AFE_RATE_352K;
> +	case 384000:
> +		return MTK_AFE_RATE_384K;
> +	default:
> +		dev_info(dev, "%s(), rate %u invalid, use %d!!!\n",
> +			 __func__,
> +			 rate, MTK_AFE_RATE_48K);

dev_err(); ... and don't return here, but...

> +		return MTK_AFE_RATE_48K;
> +	}


... return here, outside of the switch.

> +}
> +
> +static unsigned int tdm_rate_transform(struct device *dev,
> +				       unsigned int rate)
> +{
> +	switch (rate) {
> +	case 8000:
> +		return MTK_AFE_TDM_RATE_8K;
> +	case 11025:
> +		return MTK_AFE_TDM_RATE_11K;
> +	case 12000:
> +		return MTK_AFE_TDM_RATE_12K;
> +	case 16000:
> +		return MTK_AFE_TDM_RATE_16K;
> +	case 22050:
> +		return MTK_AFE_TDM_RATE_22K;
> +	case 24000:
> +		return MTK_AFE_TDM_RATE_24K;
> +	case 32000:
> +		return MTK_AFE_TDM_RATE_32K;
> +	case 44100:
> +		return MTK_AFE_TDM_RATE_44K;
> +	case 48000:
> +		return MTK_AFE_TDM_RATE_48K;
> +	case 64000:
> +		return MTK_AFE_TDM_RATE_64K;
> +	case 88200:
> +		return MTK_AFE_TDM_RATE_88K;
> +	case 96000:
> +		return MTK_AFE_TDM_RATE_96K;
> +	case 128000:
> +		return MTK_AFE_TDM_RATE_128K;
> +	case 176400:
> +		return MTK_AFE_TDM_RATE_176K;
> +	case 192000:
> +		return MTK_AFE_TDM_RATE_192K;
> +	case 256000:
> +		return MTK_AFE_TDM_RATE_256K;
> +	case 352800:
> +		return MTK_AFE_TDM_RATE_352K;
> +	case 384000:
> +		return MTK_AFE_TDM_RATE_384K;
> +	default:
> +		dev_info(dev, "%s(), rate %u invalid, use %d!!!\n",
> +			 __func__,
> +			 rate, MTK_AFE_TDM_RATE_48K);
> +		return MTK_AFE_TDM_RATE_48K;

ditto.
here and for all the other instances.

> +	}
> +}
> +

...snip...

> +}
> diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> new file mode 100644
> index 000000000000..e1e17a934245
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> @@ -0,0 +1,3029 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// Mediatek ALSA SoC AFE platform driver for 8186
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +#include <sound/soc.h>
> +
> +#include "../common/mtk-afe-platform-driver.h"
> +#include "../common/mtk-afe-fe-dai.h"
> +
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-afe-gpio.h"
> +#include "mt8186-interconnection.h"
> +
> +static const struct snd_pcm_hardware mt8186_afe_hardware = {
> +	.info = (SNDRV_PCM_INFO_MMAP |
> +		 SNDRV_PCM_INFO_INTERLEAVED |
> +		 SNDRV_PCM_INFO_MMAP_VALID),
> +	.formats = (SNDRV_PCM_FMTBIT_S16_LE |
> +		    SNDRV_PCM_FMTBIT_S24_LE |
> +		    SNDRV_PCM_FMTBIT_S32_LE),
> +	.period_bytes_min = 96,
> +	.period_bytes_max = 4 * 48 * 1024,
> +	.periods_min = 2,
> +	.periods_max = 256,
> +	.buffer_bytes_max = 4 * 48 * 1024,
> +	.fifo_size = 0,
> +};
> +
> +static int mt8186_fe_startup(struct snd_pcm_substream *substream,
> +			     struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> +	const struct snd_pcm_hardware *mtk_afe_hardware = afe->mtk_afe_hardware;
> +	int ret;
> +
> +	memif->substream = substream;
> +
> +	snd_pcm_hw_constraint_step(substream->runtime, 0,
> +				   SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
> +
> +	snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
> +
> +	ret = snd_pcm_hw_constraint_integer(runtime,
> +					    SNDRV_PCM_HW_PARAM_PERIODS);
> +	if (ret < 0)
> +		dev_info(afe->dev, "snd_pcm_hw_constraint_integer failed\n");

	if (ret < 0) {
		dev_err .....
		return ret;
	}

> +
> +	/* dynamic allocate irq to memif */
> +	if (memif->irq_usage < 0) {
> +		int irq_id = mtk_dynamic_irq_acquire(afe);
> +
> +		if (irq_id != afe->irqs_size) {
> +			/* link */
> +			memif->irq_usage = irq_id;
> +		} else {
> +			dev_info(afe->dev, "%s() error: no more asys irq\n",
> +				 __func__);
> +			ret = -EBUSY;
			return -EBUSY;
> +		}
> +	}
> +

	return 0;

> +	return ret;
> +}
> +
> +static void mt8186_fe_shutdown(struct snd_pcm_substream *substream,
> +			       struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> +	int irq_id = memif->irq_usage;
> +
> +	memif->substream = NULL;
> +	afe_priv->irq_cnt[id] = 0;
> +	afe_priv->xrun_assert[id] = 0;
> +
> +	if (!memif->const_irq) {
> +		mtk_dynamic_irq_release(afe, irq_id);
> +		memif->irq_usage = -1;
> +		memif->substream = NULL;
> +	}
> +}
> +
> +static int mt8186_fe_hw_params(struct snd_pcm_substream *substream,
> +			       struct snd_pcm_hw_params *params,
> +			       struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +	unsigned int channels = params_channels(params);
> +	unsigned int rate = params_rate(params);
> +	int ret;
> +
> +	ret = mtk_afe_fe_hw_params(substream, params, dai);
> +	if (ret)
		return ret;
> +		goto exit;
> +
> +	/* channel merge configuration, enable control is in UL5_IN_MUX */
> +	if (id == MT8186_MEMIF_VUL3) {
> +		int update_cnt = 8;
> +		unsigned int val = 0;
> +		unsigned int mask = 0;
> +		int fs_mode = mt8186_rate_transform(afe->dev, rate, id);
> +
> +		/* set rate, channel, update cnt, disable sgen */
> +		val = fs_mode << CM1_FS_SELECT_SFT |
> +			(channels - 1) << CHANNEL_MERGE0_CHNUM_SFT |
> +			update_cnt << CHANNEL_MERGE0_UPDATE_CNT_SFT |
> +			0 << CHANNEL_MERGE0_DEBUG_MODE_SFT |
> +			0 << CM1_DEBUG_MODE_SEL_SFT;

0 << number == 0!!!

> +		mask = CM1_FS_SELECT_MASK_SFT |
> +			CHANNEL_MERGE0_CHNUM_MASK_SFT |
> +			CHANNEL_MERGE0_UPDATE_CNT_MASK_SFT |
> +			CHANNEL_MERGE0_DEBUG_MODE_MASK_SFT |
> +			CM1_DEBUG_MODE_SEL_MASK_SFT;
> +		regmap_update_bits(afe->regmap, AFE_CM1_CON, mask, val);
> +	}
> +

	return 0;

... and remove the label, as it's not needed
> +exit:
> +	return ret;
> +}
> +
> +static int mt8186_fe_hw_free(struct snd_pcm_substream *substream,
> +			     struct snd_soc_dai *dai)
> +{
> +	int ret;
> +
> +	ret = mtk_afe_fe_hw_free(substream, dai);
> +	if (ret)
> +		goto exit;
> +
> +	/* wait for some platform related operation */
> +exit:
> +	return ret;
> +}
> +
> +static int mt8186_fe_trigger(struct snd_pcm_substream *substream, int cmd,
> +			     struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct snd_pcm_runtime * const runtime = substream->runtime;
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> +	int irq_id = memif->irq_usage;
> +	struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> +	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> +	unsigned int counter = runtime->period_size;
> +	unsigned int rate = runtime->rate;
> +	int fs;
> +	int ret;
> +
> +	dev_info(afe->dev, "%s(), %s cmd %d, irq_id %d\n",
> +		 __func__, memif->data->name, cmd, irq_id);


dev_dbg()

> +
> +	switch (cmd) {
> +	case SNDRV_PCM_TRIGGER_START:
> +	case SNDRV_PCM_TRIGGER_RESUME:
> +		ret = mtk_memif_set_enable(afe, id);
		if (ret) {
			dev_err ........
			return ret;
		}

		/*
		 * for small latency record
		 * ul memif need read some data before irq enable
		 */
		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
		    ((runtime->period_size * 1000) / rate) <= 10)
				usleep_range(300, 310);


> +		/*
> +		 * for small latency record
> +		 * ul memif need read some data before irq enable
> +		 */
> +		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
> +			if ((runtime->period_size * 1000) / rate <= 10)
> +				usleep_range(300, 310);
> +		}
> +
> +		if (ret) {
> +			dev_info(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
> +				 __func__, id, ret);
> +			return ret;
> +		}
> +
> +		/* set irq counter */
> +		if (afe_priv->irq_cnt[id] > 0)
> +			counter = afe_priv->irq_cnt[id];
> +
> +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> +				   irq_data->irq_cnt_maskbit
> +				   << irq_data->irq_cnt_shift,
> +				   counter << irq_data->irq_cnt_shift);
> +
> +		/* set irq fs */
> +		fs = afe->irq_fs(substream, runtime->rate);
> +

empty line: remove.

> +		if (fs < 0)
> +			return -EINVAL;
> +
> +		regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
> +				   irq_data->irq_fs_maskbit
> +				   << irq_data->irq_fs_shift,
> +				   fs << irq_data->irq_fs_shift);
> +
> +		/* enable interrupt */
> +		if (runtime->stop_threshold != ~(0U))
> +			regmap_update_bits(afe->regmap,
> +					   irq_data->irq_en_reg,
> +					   1 << irq_data->irq_en_shift,
> +					   1 << irq_data->irq_en_shift);
> +		return 0;
> +	case SNDRV_PCM_TRIGGER_STOP:
> +	case SNDRV_PCM_TRIGGER_SUSPEND:
> +		if (afe_priv->xrun_assert[id] > 0) {
> +			if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
> +				int avail = snd_pcm_capture_avail(runtime);
> +
> +				if (avail >= runtime->buffer_size) {
> +					dev_info(afe->dev, "%s(), id %d, xrun assert\n",
> +						 __func__, id);
> +				}
> +			}
> +		}
> +
> +		ret = mtk_memif_set_disable(afe, id);
> +		if (ret) {
> +			dev_info(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
> +				 __func__, id, ret);

dev_err()

> +		}
> +
> +		/* disable interrupt */
> +		if (runtime->stop_threshold != ~(0U))
> +			regmap_update_bits(afe->regmap,
> +					   irq_data->irq_en_reg,
> +					   1 << irq_data->irq_en_shift,
> +					   0 << irq_data->irq_en_shift);
> +
> +		/* clear pending IRQ */
> +		regmap_write(afe->regmap, irq_data->irq_clr_reg,
> +			     1 << irq_data->irq_clr_shift);
> +		return ret;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int mt8186_memif_fs(struct snd_pcm_substream *substream,
> +			   unsigned int rate)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct snd_soc_component *component =
> +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +
> +	return mt8186_rate_transform(afe->dev, rate, id);
> +}
> +
> +static int mt8186_get_dai_fs(struct mtk_base_afe *afe,
> +			     int dai_id, unsigned int rate)
> +{
> +	return mt8186_rate_transform(afe->dev, rate, dai_id);
> +}
> +
> +static int mt8186_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct snd_soc_component *component =
> +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
> +
> +	return mt8186_general_rate_transform(afe->dev, rate);
> +}
> +
> +static int mt8186_get_memif_pbuf_size(struct snd_pcm_substream *substream)
> +{
> +	struct snd_pcm_runtime *runtime = substream->runtime;
> +
> +	if ((runtime->period_size * 1000) / runtime->rate > 10)
> +		return MT8186_MEMIF_PBUF_SIZE_256_BYTES;
> +	else

drop "else"... and just return MT8186_MEMIF_PBUF_SIZE_32_BYTES

> +		return MT8186_MEMIF_PBUF_SIZE_32_BYTES;
> +}
> +
> +static int mt8186_fe_prepare(struct snd_pcm_substream *substream,
> +			     struct snd_soc_dai *dai)
> +{
> +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> +	struct snd_pcm_runtime * const runtime = substream->runtime;
> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> +	int irq_id = memif->irq_usage;
> +	struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> +	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> +	unsigned int counter = runtime->period_size;
> +	int fs;
> +	int ret;
> +
> +	ret = mtk_afe_fe_prepare(substream, dai);
> +	if (ret)

		return ret;

> +		goto exit;
> +
> +	/* set irq counter */
> +	regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> +			   irq_data->irq_cnt_maskbit
> +			   << irq_data->irq_cnt_shift,
> +			   counter << irq_data->irq_cnt_shift);
> +
> +	/* set irq fs */
> +	fs = afe->irq_fs(substream, runtime->rate);
> +
> +	if (fs < 0)
> +		return -EINVAL;
> +
> +	regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
> +			   irq_data->irq_fs_maskbit
> +			   << irq_data->irq_fs_shift,
> +			   fs << irq_data->irq_fs_shift);
> +exit:

unneeded label, and return 0;

> +	return ret;
> +}
> +

..snip..

> +static int mt8186_irq_cnt1_set(struct snd_kcontrol *kcontrol,
> +			       struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int memif_num = MT8186_PRIMARY_MEMIF;
> +	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
> +	int irq_id = memif->irq_usage;
> +	int irq_cnt = afe_priv->irq_cnt[memif_num];
> +
> +	dev_info(afe->dev, "%s(), irq_id %d, irq_cnt = %d, value = %ld\n",
> +		 __func__,
> +		 irq_id, irq_cnt,
> +		 ucontrol->value.integer.value[0]);

dev_dbg() - and fits in less lines.

> +
> +	if (irq_cnt == ucontrol->value.integer.value[0])
> +		return 0;
> +
> +	irq_cnt = ucontrol->value.integer.value[0];
> +	afe_priv->irq_cnt[memif_num] = irq_cnt;
> +
> +	if (pm_runtime_status_suspended(afe->dev) || irq_id < 0) {
> +		dev_info(afe->dev, "%s(), suspended || irq_id %d, not set\n",
> +			 __func__, irq_id);
> +	} else {
> +		struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> +		const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> +
> +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> +				   irq_data->irq_cnt_maskbit
> +				   << irq_data->irq_cnt_shift,
> +				   irq_cnt << irq_data->irq_cnt_shift);
> +	}
> +
> +	return 0;
> +}
> +
> +static int mt8186_irq_cnt2_get(struct snd_kcontrol *kcontrol,
> +			       struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	ucontrol->value.integer.value[0] =
> +		afe_priv->irq_cnt[MT8186_RECORD_MEMIF];
> +	return 0;
> +}
> +
> +static int mt8186_irq_cnt2_set(struct snd_kcontrol *kcontrol,
> +			       struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int memif_num = MT8186_RECORD_MEMIF;
> +	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
> +	int irq_id = memif->irq_usage;
> +	int irq_cnt = afe_priv->irq_cnt[memif_num];
> +
> +	dev_info(afe->dev, "%s(), irq_id %d, irq_cnt = %d, value = %ld\n",
> +		 __func__,
> +		 irq_id, irq_cnt,
> +		 ucontrol->value.integer.value[0]);

dev_dbg() - and fits in less lines.

> +
> +	if (irq_cnt == ucontrol->value.integer.value[0])
> +		return 0;
> +
> +	irq_cnt = ucontrol->value.integer.value[0];
> +	afe_priv->irq_cnt[memif_num] = irq_cnt;
> +
> +	if (pm_runtime_status_suspended(afe->dev) || irq_id < 0) {
> +		dev_info(afe->dev, "%s(), suspended || irq_id %d, not set\n",
> +			 __func__, irq_id);
> +	} else {
> +		struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> +		const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> +
> +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> +				   irq_data->irq_cnt_maskbit
> +				   << irq_data->irq_cnt_shift,
> +				   irq_cnt << irq_data->irq_cnt_shift);
> +	}
> +
> +	return 0;
> +}
> +



> +
> +static irqreturn_t mt8186_afe_irq_handler(int irq_id, void *dev)
> +{
> +	struct mtk_base_afe *afe = dev;
> +	struct mtk_base_afe_irq *irq;
> +	unsigned int status;
> +	unsigned int status_mcu;
> +	unsigned int mcu_en;
> +	int ret;
> +	int i;
> +
> +	/* get irq that is sent to MCU */
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);

ret = regmap_read ....
if (ret) ....

> +
> +	ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
> +	/* only care IRQ which is sent to MCU */
> +	status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
> +
> +	if (ret || status_mcu == 0) {
> +		dev_info(afe->dev, "%s(), irq status err, ret %d, status 0x%x, mcu_en 0x%x\n",
> +			 __func__, ret, status, mcu_en);

dev_err()

> +
> +		goto err_irq;
> +	}
> +
> +	for (i = 0; i < MT8186_MEMIF_NUM; i++) {
> +		struct mtk_base_afe_memif *memif = &afe->memif[i];
> +
> +		if (!memif->substream)
> +			continue;
> +
> +		if (memif->irq_usage < 0)
> +			continue;
> +
> +		irq = &afe->irqs[memif->irq_usage];
> +
> +		if (status_mcu & (1 << irq->irq_data->irq_en_shift))
> +			snd_pcm_period_elapsed(memif->substream);
> +	}
> +
> +err_irq:
> +	/* clear irq */
> +	regmap_write(afe->regmap,
> +		     AFE_IRQ_MCU_CLR,
> +		     status_mcu);

fits in a single line.

> +
> +	return IRQ_HANDLED;
> +}
> +
> +static int mt8186_afe_runtime_suspend(struct device *dev)
> +{
> +	struct mtk_base_afe *afe = dev_get_drvdata(dev);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	unsigned int value = 0;
> +	int ret;
> +
> +	if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
> +		goto skip_regmap;
> +
> +	/* disable AFE */
> +	regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
> +
> +	ret = regmap_read_poll_timeout(afe->regmap,
> +				       AFE_DAC_MON,
> +				       value,
> +				       (value & AFE_ON_RETM_MASK_SFT) == 0,
> +				       20,
> +				       1 * 1000 * 1000);
> +	if (ret)
> +		dev_info(afe->dev, "%s(), ret %d\n", __func__, ret);

dev_err()!!
P.S.: Are you sure that we shouldn't return here?

> +
> +	/* make sure all irq status are cleared */
> +	regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, 0xffffffff);
> +	regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, 0xffffffff);
> +
> +	/* reset sgen */
> +	regmap_write(afe->regmap, AFE_SINEGEN_CON0, 0x0);
> +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> +			   INNER_LOOP_BACK_MODE_MASK_SFT,
> +			   0x3f << INNER_LOOP_BACK_MODE_SFT);
> +
> +	/* cache only */
> +	regcache_cache_only(afe->regmap, true);
> +	regcache_mark_dirty(afe->regmap);
> +
> +skip_regmap:
> +	mt8186_afe_disable_cgs(afe);
> +	mt8186_afe_disable_clock(afe);
> +
> +	return 0;
> +}
> +
> +static int mt8186_afe_runtime_resume(struct device *dev)
> +{
> +	struct mtk_base_afe *afe = dev_get_drvdata(dev);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	int ret;
> +
> +	ret = mt8186_afe_enable_clock(afe);
> +	if (ret)
> +		return ret;
> +
> +	ret = mt8186_afe_enable_cgs(afe);
> +	if (ret)
> +		return ret;
> +
> +	if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
> +		goto skip_regmap;
> +
> +	regcache_cache_only(afe->regmap, false);
> +	regcache_sync(afe->regmap);
> +
> +	/* enable audio sys DCM for power saving */
> +	regmap_update_bits(afe_priv->infracfg,
> +			   PERI_BUS_DCM_CTRL, 0x1 << 29, 0x1 << 29);

BIT(29)

> +	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 0x1 << 29, 0x1 << 29);
> +
> +	/* force cpu use 8_24 format when writing 32bit data */
> +	regmap_update_bits(afe->regmap, AFE_MEMIF_CON0,
> +			   CPU_HD_ALIGN_MASK_SFT, 0 << CPU_HD_ALIGN_SFT);

0 << number == 0, so write 0

> +
> +	/* set all output port to 24bit */
> +	regmap_write(afe->regmap, AFE_CONN_24BIT, 0xffffffff);
> +	regmap_write(afe->regmap, AFE_CONN_24BIT_1, 0xffffffff);
> +
> +	/* enable AFE */
> +	regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
> +
> +skip_regmap:
> +	return 0;
> +}

..snip..

> +static int mt8186_afe_pcm_dev_probe(struct platform_device *pdev)
> +{
> +	struct mtk_base_afe *afe;
> +	struct mt8186_afe_private *afe_priv;
> +	struct resource *res;
> +	struct reset_control *rstc;
> +	struct device *dev = &pdev->dev;
> +	int i, ret, irq_id;
> +
> +	dev_info(dev, "%s(), ++\n", __func__);

Drop this print.

> +
> +	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(34));
> +	if (ret)
> +		return ret;
> +
> +	afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
> +	if (!afe)
> +		return -ENOMEM;
> +	platform_set_drvdata(pdev, afe);
> +
> +	afe->platform_priv = devm_kzalloc(dev, sizeof(*afe_priv), GFP_KERNEL);
> +	if (!afe->platform_priv)
> +		return -ENOMEM;
> +
> +	afe_priv = afe->platform_priv;
> +	afe->dev = &pdev->dev;
> +
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
> +	if (IS_ERR(afe->base_addr))
> +		return PTR_ERR(afe->base_addr);
> +
> +	dev_info(dev, "%s(), mt8186_init_clock\n", __func__);

Drop this print.

> +	/* init audio related clock */
> +	ret = mt8186_init_clock(afe);
> +	if (ret) {
> +		dev_info(dev, "init clock error\n");

dev_err()

> +		return ret;
> +	}
> +
> +	/* init memif */
> +	afe->memif_32bit_supported = 0;
> +	afe->memif_size = MT8186_MEMIF_NUM;
> +	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
> +				  GFP_KERNEL);
> +
> +	if (!afe->memif)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < afe->memif_size; i++) {
> +		afe->memif[i].data = &memif_data[i];
> +		afe->memif[i].irq_usage = memif_irq_usage[i];
> +		afe->memif[i].const_irq = 1;
> +	}
> +
> +	mutex_init(&afe->irq_alloc_lock);	/* needed when dynamic irq */
> +
> +	dev_info(dev, "%s(), init irq\n", __func__);

Drop this print.

> +
> +	/* init irq */
> +	afe->irqs_size = MT8186_IRQ_NUM;
> +	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
> +				 GFP_KERNEL);
> +
> +	if (!afe->irqs)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < afe->irqs_size; i++)
> +		afe->irqs[i].irq_data = &irq_data[i];
> +
> +	dev_info(dev, "%s(), devm_request_irq\n", __func__);

Drop.

> +
> +	/* request irq */
> +	irq_id = platform_get_irq(pdev, 0);
> +	if (irq_id <= 0) {
> +		dev_info(dev, "%pOFn no irq found\n", dev->of_node);

		return dev_err_probe(dev, irq_id < 0 ? irq_id : -ENXIO,
				     "no irq found");

> +		return irq_id < 0 ? irq_id : -ENXIO;
> +	}
> +	ret = devm_request_irq(dev, irq_id, mt8186_afe_irq_handler,
> +			       IRQF_TRIGGER_NONE,
> +			       "Afe_ISR_Handle", (void *)afe);
> +	if (ret) {
> +		dev_info(dev, "could not request_irq for Afe_ISR_Handle\n");

return dev_err_probe(dev, ret, "could not request Afe_ISR_Handle irq\n");

> +		return ret;
> +	}
> +
> +	ret = enable_irq_wake(irq_id);
> +	if (ret < 0)
> +		dev_info(dev, "enable_irq_wake %d err: %d\n", irq_id, ret);

Isn't this a critical error?
		return dev_err_probe(.......

> +
> +	/* init sub_dais */
> +	INIT_LIST_HEAD(&afe->sub_dais);
> +
> +	for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
> +		ret = dai_register_cbs[i](afe);
> +		if (ret) {
> +			dev_info(dev, "dai register i %d fail, ret %d\n",
> +				 i, ret);
> +			return ret;

return dev_err_probe()

> +		}
> +	}
> +
> +	dev_info(dev, "%s(), mtk_afe_combine_sub_dai\n", __func__);

drop this.

> +
> +	/* init dai_driver and component_driver */
> +	ret = mtk_afe_combine_sub_dai(afe);
> +	if (ret) {
> +		dev_info(dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
> +			 ret);
> +		return ret;

return dev_err_probe()

> +	}
> +
> +	/* reset controller to reset audio regs before regmap cache */
> +	rstc = devm_reset_control_get_exclusive(dev, "audiosys");
> +	if (IS_ERR(rstc)) {
> +		ret = PTR_ERR(rstc);
> +		dev_info(dev, "could not get audiosys reset:%d\n", ret);
> +		return ret;

return dev_err_probe(dev, PTR_ERR(rstc), "Could not get audiosys reset\n");

> +	}
> +
> +	ret = reset_control_reset(rstc);
> +	if (ret) {
> +		dev_info(dev, "failed to trigger audio reset:%d\n", ret);
> +		return ret;

dev_err_probe()

> +	}
> +
> +	/* enable clock for regcache get default value from hw */
> +	afe_priv->pm_runtime_bypass_reg_ctl = true;
> +	pm_runtime_enable(dev);
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret)
> +		dev_info(dev, "get_ret:%d, rpm_error:%d\n",
> +			 ret, dev->power.runtime_error);

You should also return the error here.

> +
> +	afe->regmap = devm_regmap_init_mmio(dev, afe->base_addr,
> +					    &mt8186_afe_regmap_config);
> +	if (IS_ERR(afe->regmap)) {
> +		ret = PTR_ERR(afe->regmap);
> +		goto err_pm_disable;
> +	}
> +
> +	/* others */
> +	afe->mtk_afe_hardware = &mt8186_afe_hardware;
> +	afe->memif_fs = mt8186_memif_fs;
> +	afe->irq_fs = mt8186_irq_fs;
> +	afe->get_dai_fs = mt8186_get_dai_fs;
> +	afe->get_memif_pbuf_size = mt8186_get_memif_pbuf_size;
> +
> +	afe->runtime_resume = mt8186_afe_runtime_resume;
> +	afe->runtime_suspend = mt8186_afe_runtime_suspend;
> +
> +	/* register platform */
> +	dev_info(dev, "%s(), devm_snd_soc_register_component\n", __func__);
> +
> +	ret = devm_snd_soc_register_component(dev,
> +					      &mt8186_afe_component,
> +					      afe->dai_drivers,
> +					      afe->num_dai_drivers);
> +	if (ret) {
> +		dev_info(dev, "err_dai_component\n");

dev_err()

> +		goto err_pm_disable;
> +	}
> +
> +	ret = pm_runtime_put_sync(dev);
> +	if (ret)
> +		dev_info(dev, "put_ret:%d, rpm_error:%d\n",
> +			 ret, dev->power.runtime_error);

dev_err()

> +	afe_priv->pm_runtime_bypass_reg_ctl = false;
> +
> +	regcache_cache_only(afe->regmap, true);
> +	regcache_mark_dirty(afe->regmap);
> +
> +	dev_info(dev, "%s(), --\n", __func__);
> +
> +	return 0;
> +
> +err_pm_disable:
> +	pm_runtime_put_sync(dev);
> +	pm_runtime_disable(dev);
> +
> +	return ret;
> +}
> +
> +static int mt8186_afe_pcm_dev_remove(struct platform_device *pdev)
> +{
> +	struct mtk_base_afe *afe = platform_get_drvdata(pdev);
> +
> +	pm_runtime_disable(&pdev->dev);
> +	if (!pm_runtime_status_suspended(&pdev->dev))
> +		mt8186_afe_runtime_suspend(&pdev->dev);
> +
> +	mt8186_deinit_clock(afe);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id mt8186_afe_pcm_dt_match[] = {
> +	{ .compatible = "mediatek,mt8186-sound", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, mt8186_afe_pcm_dt_match);
> +
> +static const struct dev_pm_ops mt8186_afe_pm_ops = {
> +	SET_RUNTIME_PM_OPS(mt8186_afe_runtime_suspend,
> +			   mt8186_afe_runtime_resume, NULL)
> +};
> +
> +static struct platform_driver mt8186_afe_pcm_driver = {
> +	.driver = {
> +		   .name = "mt8186-audio",
> +		   .of_match_table = mt8186_afe_pcm_dt_match,
> +		   .pm = &mt8186_afe_pm_ops,
> +	},
> +	.probe = mt8186_afe_pcm_dev_probe,
> +	.remove = mt8186_afe_pcm_dev_remove,
> +};
> +
> +module_platform_driver(mt8186_afe_pcm_driver);
> +
> +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8186");
> +MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
> +MODULE_LICENSE("GPL v2");
> diff --git a/sound/soc/mediatek/mt8186/mt8186-interconnection.h b/sound/soc/mediatek/mt8186/mt8186-interconnection.h
> new file mode 100644
> index 000000000000..5b188d93ebd3
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-interconnection.h
> @@ -0,0 +1,69 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * Mediatek MT8186 audio driver interconnection definition
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> + */
> +
> +#ifndef _MT8186_INTERCONNECTION_H_
> +#define _MT8186_INTERCONNECTION_H_
> +
> +/* in port define */
> +#define I_I2S0_CH1 0
> +#define I_I2S0_CH2 1
> +#define I_ADDA_UL_CH1 3
> +#define I_ADDA_UL_CH2 4
> +#define I_DL1_CH1 5
> +#define I_DL1_CH2 6
> +#define I_DL2_CH1 7
> +#define I_DL2_CH2 8
> +#define I_PCM_1_CAP_CH1 9
> +#define I_GAIN1_OUT_CH1 10
> +#define I_GAIN1_OUT_CH2 11
> +#define I_GAIN2_OUT_CH1 12
> +#define I_GAIN2_OUT_CH2 13
> +#define I_PCM_2_CAP_CH1 14
> +#define I_ADDA_UL_CH3 17
> +#define I_ADDA_UL_CH4 18
> +#define I_DL12_CH1 19
> +#define I_DL12_CH2 20
> +#define I_DL12_CH3 5
> +#define I_DL12_CH4 6
> +#define I_PCM_2_CAP_CH2 21
> +#define I_PCM_1_CAP_CH2 22
> +#define I_DL3_CH1 23
> +#define I_DL3_CH2 24
> +#define I_I2S2_CH1 25
> +#define I_I2S2_CH2 26
> +#define I_I2S2_CH3 27
> +#define I_I2S2_CH4 28
> +
> +/* in port define >= 32 */
> +#define I_32_OFFSET 32
> +#define I_CONNSYS_I2S_CH1 (34 - I_32_OFFSET)
> +#define I_CONNSYS_I2S_CH2 (35 - I_32_OFFSET)
> +#define I_SRC_1_OUT_CH1 (36 - I_32_OFFSET)
> +#define I_SRC_1_OUT_CH2 (37 - I_32_OFFSET)
> +#define I_SRC_2_OUT_CH1 (38 - I_32_OFFSET)
> +#define I_SRC_2_OUT_CH2 (39 - I_32_OFFSET)
> +#define I_DL4_CH1 (40 - I_32_OFFSET)
> +#define I_DL4_CH2 (41 - I_32_OFFSET)
> +#define I_DL5_CH1 (42 - I_32_OFFSET)
> +#define I_DL5_CH2 (43 - I_32_OFFSET)
> +#define I_DL6_CH1 (44 - I_32_OFFSET)
> +#define I_DL6_CH2 (45 - I_32_OFFSET)
> +#define I_DL7_CH1 (46 - I_32_OFFSET)
> +#define I_DL7_CH2 (47 - I_32_OFFSET)
> +#define I_DL8_CH1 (48 - I_32_OFFSET)
> +#define I_DL8_CH2 (49 - I_32_OFFSET)
> +#define I_TDM_IN_CH1 (56 - I_32_OFFSET)
> +#define I_TDM_IN_CH2 (57 - I_32_OFFSET)
> +#define I_TDM_IN_CH3 (58 - I_32_OFFSET)
> +#define I_TDM_IN_CH4 (59 - I_32_OFFSET)
> +#define I_TDM_IN_CH5 (60 - I_32_OFFSET)
> +#define I_TDM_IN_CH6 (61 - I_32_OFFSET)
> +#define I_TDM_IN_CH7 (62 - I_32_OFFSET)
> +#define I_TDM_IN_CH8 (63 - I_32_OFFSET)
> +
> +#endif
> diff --git a/sound/soc/mediatek/mt8186/mt8186-misc-control.c b/sound/soc/mediatek/mt8186/mt8186-misc-control.c
> new file mode 100644
> index 000000000000..c097248b37b6
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c
> @@ -0,0 +1,1728 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// MediaTek ALSA SoC Audio Misc Control
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +#include <sound/soc.h>
> +
> +#include "../common/mtk-afe-fe-dai.h"
> +#include "../common/mtk-afe-platform-driver.h"
> +#include "mt8186-afe-common.h"
> +
> +#define SGEN_MUTE_CH1_KCONTROL_NAME "Audio_SineGen_Mute_Ch1"
> +#define SGEN_MUTE_CH2_KCONTROL_NAME "Audio_SineGen_Mute_Ch2"
> +
> +static const char * const mt8186_sgen_mode_str[] = {
> +	"I0I1",   "I2",     "I3I4",   "I5I6",
> +	"I7I8",   "I9I22",  "I10I11", "I12I13",
> +	"I14I21", "I15I16", "I17I18", "I19I20",
> +	"I23I24", "I25I26", "I27I28", "I33",
> +	"I34I35", "I36I37", "I38I39", "I40I41",
> +	"I42I43", "I44I45", "I46I47", "I48I49",
> +	"I56I57", "I58I59", "I60I61", "I62I63",
> +	"O0O1",   "O2",     "O3O4",   "O5O6",
> +	"O7O8",   "O9O10",  "O11",    "O12",
> +	"O13O14", "O15O16", "O17O18", "O19O20",
> +	"O21O22", "O23O24", "O25",    "O28O29",
> +	"O34",    "O35",    "O32O33", "O36O37",
> +	"O38O39", "O30O31", "O40O41", "O42O43",
> +	"O44O45", "O46O47", "O48O49", "O50O51",
> +	"O58O59", "O60O61", "O62O63", "O64O65",
> +	"O66O67", "O68O69", "O26O27", "OFF",
> +};
> +
> +static const int mt8186_sgen_mode_idx[] = {
> +	0, 2, 4, 6,
> +	8, 22, 10, 12,
> +	14, -1, 18, 20,
> +	24, 26, 28, 33,
> +	34, 36, 38, 40,
> +	42, 44, 46, 48,
> +	56, 58, 60, 62,
> +	128, 130, 132, 134,
> +	135, 138, 139, 140,
> +	142, 144, 166, 148,
> +	150, 152, 153, 156,
> +	162, 163, 160, 164,
> +	166, -1, 168, 170,
> +	172, 174, 176, 178,
> +	186, 188, 190, 192,
> +	194, 196, -1, -1,
> +};
> +
> +static const char * const mt8186_sgen_rate_str[] = {
> +	"8K", "11K", "12K", "16K",
> +	"22K", "24K", "32K", "44K",
> +	"48K", "88k", "96k", "176k",
> +	"192k"
> +};
> +
> +static const int mt8186_sgen_rate_idx[] = {
> +	0, 1, 2, 4,
> +	5, 6, 8, 9,
> +	10, 11, 12, 13,
> +	14
> +};
> +
> +/* this order must match reg bit amp_div_ch1/2 */
> +static const char * const mt8186_sgen_amp_str[] = {
> +	"1/128", "1/64", "1/32", "1/16", "1/8", "1/4", "1/2", "1" };
> +static const char * const mt8186_sgen_mute_str[] = {
> +	"Off", "On"
> +};
> +
> +static int mt8186_sgen_get(struct snd_kcontrol *kcontrol,
> +			   struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	ucontrol->value.integer.value[0] = afe_priv->sgen_mode;
> +	return 0;
> +}
> +
> +static int mt8186_sgen_set(struct snd_kcontrol *kcontrol,
> +			   struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int mode;
> +	int mode_idx;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	mode = ucontrol->value.integer.value[0];
> +	mode_idx = mt8186_sgen_mode_idx[mode];
> +
> +	dev_info(afe->dev, "%s(), mode %d, mode_idx %d\n",
> +		 __func__, mode, mode_idx);
> +
> +	if (mode_idx >= 0) {
> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> +				   INNER_LOOP_BACK_MODE_MASK_SFT,
> +				   mode_idx << INNER_LOOP_BACK_MODE_SFT);
> +		//regmap_write(afe->regmap, AFE_SINEGEN_CON0, 0x04ac2ac1);

Why is this commented out?
Either remove the comment, or remove the line entirely.

> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +				   DAC_EN_MASK_SFT,
> +				   0x1 << DAC_EN_SFT);

BIT()

> +	} else {
> +		/* disable sgen */
> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +				   DAC_EN_MASK_SFT,
> +				   0x0);
> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> +				   INNER_LOOP_BACK_MODE_MASK_SFT,
> +				   0x3f << INNER_LOOP_BACK_MODE_SFT);
> +	}
> +
> +	afe_priv->sgen_mode = mode;
> +	return 0;
> +}
> +
> +static int mt8186_sgen_rate_get(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	ucontrol->value.integer.value[0] = afe_priv->sgen_rate;
> +	return 0;
> +}
> +
> +static int mt8186_sgen_rate_set(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int rate;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	rate = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), rate %d\n", __func__, rate);

dev_dbg()

> +
> +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +			   SINE_MODE_CH1_MASK_SFT,
> +			   mt8186_sgen_rate_idx[rate] << SINE_MODE_CH1_SFT);
> +
> +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +			   SINE_MODE_CH2_MASK_SFT,
> +			   mt8186_sgen_rate_idx[rate] << SINE_MODE_CH2_SFT);
> +
> +	afe_priv->sgen_rate = rate;
> +	return 0;
> +}
> +
> +static int mt8186_sgen_amplitude_get(struct snd_kcontrol *kcontrol,
> +				     struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +
> +	ucontrol->value.integer.value[0] = afe_priv->sgen_amplitude;
> +	return 0;
> +}
> +
> +static int mt8186_sgen_amplitude_set(struct snd_kcontrol *kcontrol,
> +				     struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int amplitude;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	amplitude = ucontrol->value.integer.value[0];
> +	if (amplitude > AMP_DIV_CH1_MASK) {
> +		dev_info(afe->dev, "%s(), amplitude %d invalid\n",
> +			 __func__, amplitude);

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	dev_info(afe->dev, "%s(), amplitude %d\n", __func__, amplitude);
> +
> +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +			   AMP_DIV_CH1_MASK_SFT,
> +			   amplitude << AMP_DIV_CH1_SFT);
> +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +			   AMP_DIV_CH2_MASK_SFT,
> +			   amplitude << AMP_DIV_CH2_SFT);
> +
> +	afe_priv->sgen_amplitude = amplitude;
> +
> +	return 0;
> +}
> +
> +static int mt8186_sgen_mute_get(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	int mute;
> +
> +	regmap_read(afe->regmap, AFE_SINEGEN_CON0, &mute);
> +
> +	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) == 0)
> +		return (mute >> MUTE_SW_CH1_SFT) & MUTE_SW_CH1_MASK;
> +	else
> +		return (mute >> MUTE_SW_CH2_SFT) & MUTE_SW_CH2_MASK;

	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) == 0)
		return (mute >> MUTE_SW_CH1_SFT) & MUTE_SW_CH1_MASK;

	return (mute >> MUTE_SW_CH2_SFT) & MUTE_SW_CH2_MASK;

> +}
> +
> +static int mt8186_sgen_mute_set(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
> +	int mute;
> +
> +	if (ucontrol->value.enumerated.item[0] >= e->items)
> +		return -EINVAL;
> +
> +	mute = ucontrol->value.integer.value[0];
> +
> +	dev_info(afe->dev, "%s(), kcontrol name %s, mute %d\n",
> +		 __func__, kcontrol->id.name, mute);

dev_dbg()

> +
> +	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) == 0) {
> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +				   MUTE_SW_CH1_MASK_SFT,
> +				   mute << MUTE_SW_CH1_SFT);
> +	} else {
> +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> +				   MUTE_SW_CH2_MASK_SFT,
> +				   mute << MUTE_SW_CH2_SFT);
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct soc_enum mt8186_afe_sgen_enum[] = {
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mode_str),
> +			    mt8186_sgen_mode_str),
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_rate_str),
> +			    mt8186_sgen_rate_str),
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_amp_str),
> +			    mt8186_sgen_amp_str),
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mute_str),
> +			    mt8186_sgen_mute_str),
> +};
> +
> +static const struct snd_kcontrol_new mt8186_afe_sgen_controls[] = {
> +	SOC_ENUM_EXT("Audio_SineGen_Switch", mt8186_afe_sgen_enum[0],
> +		     mt8186_sgen_get, mt8186_sgen_set),
> +	SOC_ENUM_EXT("Audio_SineGen_SampleRate", mt8186_afe_sgen_enum[1],
> +		     mt8186_sgen_rate_get, mt8186_sgen_rate_set),
> +	SOC_ENUM_EXT("Audio_SineGen_Amplitude", mt8186_afe_sgen_enum[2],
> +		     mt8186_sgen_amplitude_get, mt8186_sgen_amplitude_set),
> +	SOC_ENUM_EXT(SGEN_MUTE_CH1_KCONTROL_NAME, mt8186_afe_sgen_enum[3],
> +		     mt8186_sgen_mute_get, mt8186_sgen_mute_set),
> +	SOC_ENUM_EXT(SGEN_MUTE_CH2_KCONTROL_NAME, mt8186_afe_sgen_enum[3],
> +		     mt8186_sgen_mute_get, mt8186_sgen_mute_set),
> +	SOC_SINGLE("Audio_SineGen_Freq_Div_Ch1", AFE_SINEGEN_CON0,
> +		   FREQ_DIV_CH1_SFT, FREQ_DIV_CH1_MASK, 0),
> +	SOC_SINGLE("Audio_SineGen_Freq_Div_Ch2", AFE_SINEGEN_CON0,
> +		   FREQ_DIV_CH2_SFT, FREQ_DIV_CH2_MASK, 0),
> +};
> +
> +/* audio debug log */
> +static const char * const mt8186_afe_off_on_str[] = {
> +	"Off", "On"
> +};
> +
> +static int mt8186_afe_debug_get(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	return 0;
> +}
> +
> +static int mt8186_afe_debug_set(struct snd_kcontrol *kcontrol,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +	unsigned int value;
> +

This should be debugfs, instead of spitting a full register dump in the kmsg:
doing so is horrible (sorry).

> +	regmap_read(afe->regmap, AUDIO_TOP_CON0, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_CON1, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_CON2, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_CON3, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAC_CON0, &value);
> +	dev_info(afe->dev, "AFE_DAC_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_CON, &value);
> +	dev_info(afe->dev, "AFE_I2S_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN0, &value);
> +	dev_info(afe->dev, "AFE_CONN0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN1, &value);
> +	dev_info(afe->dev, "AFE_CONN1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN2, &value);
> +	dev_info(afe->dev, "AFE_CONN2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN3, &value);
> +	dev_info(afe->dev, "AFE_CONN3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN4, &value);
> +	dev_info(afe->dev, "AFE_CONN4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_CON1, &value);
> +	dev_info(afe->dev, "AFE_I2S_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_CON2, &value);
> +	dev_info(afe->dev, "AFE_I2S_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_CON3, &value);
> +	dev_info(afe->dev, "AFE_I2S_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN5, &value);
> +	dev_info(afe->dev, "AFE_CONN5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_24BIT, &value);
> +	dev_info(afe->dev, "AFE_CONN_24BIT = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL1_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL1_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL1_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL1_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL1_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL1_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_END, &value);
> +	dev_info(afe->dev, "AFE_DL1_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL2_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL2_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL2_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL2_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL2_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_END, &value);
> +	dev_info(afe->dev, "AFE_DL2_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL3_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL3_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL3_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL3_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL3_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL3_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_END, &value);
> +	dev_info(afe->dev, "AFE_DL3_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN6, &value);
> +	dev_info(afe->dev, "AFE_CONN6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL4_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL4_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL4_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL4_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL4_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL4_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_END, &value);
> +	dev_info(afe->dev, "AFE_DL4_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL12_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL12_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL12_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL12_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL12_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL12_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_END, &value);
> +	dev_info(afe->dev, "AFE_DL12_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SRC2_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SRC2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SRC2_CON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SRC2_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_UL_SRC_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_UL_SRC_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_UL_SRC_CON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_UL_SRC_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_TOP_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_TOP_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_UL_DL_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_UL_DL_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_SRC_DEBUG, &value);
> +	dev_info(afe->dev, "AFE_ADDA_SRC_DEBUG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_SRC_DEBUG_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_SRC_DEBUG_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_SRC_DEBUG_MON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_SRC_DEBUG_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_UL_SRC_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_UL_SRC_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_UL_SRC_MON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_UL_SRC_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_CON0, &value);
> +	dev_info(afe->dev, "AFE_SECURE_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SRAM_BOUND, &value);
> +	dev_info(afe->dev, "AFE_SRAM_BOUND = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_CON1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_CONN0, &value);
> +	dev_info(afe->dev, "AFE_SECURE_CONN0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_END, &value);
> +	dev_info(afe->dev, "AFE_VUL_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_DEBUG, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_DEBUG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_MON, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SINEGEN_CON2, &value);
> +	dev_info(afe->dev, "AFE_SINEGEN_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_CON0, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_COEFF, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_COEFF = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_CON1, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SIDETONE_GAIN, &value);
> +	dev_info(afe->dev, "AFE_SIDETONE_GAIN = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SINEGEN_CON0, &value);
> +	dev_info(afe->dev, "AFE_SINEGEN_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_TOP_CON0, &value);
> +	dev_info(afe->dev, "AFE_TOP_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL2_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL2_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL2_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL2_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL2_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_END, &value);
> +	dev_info(afe->dev, "AFE_VUL2_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL3_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL3_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL3_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL3_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL3_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL3_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_END, &value);
> +	dev_info(afe->dev, "AFE_VUL3_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_BUSY, &value);
> +	dev_info(afe->dev, "AFE_BUSY = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_BUS_CFG, &value);
> +	dev_info(afe->dev, "AFE_BUS_CFG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_PREDIS_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_PREDIS_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_PREDIS_CON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_PREDIS_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_MON, &value);
> +	dev_info(afe->dev, "AFE_I2S_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_IIR_COEF_02_01, &value);
> +	dev_info(afe->dev, "AFE_ADDA_IIR_COEF_02_01 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_IIR_COEF_04_03, &value);
> +	dev_info(afe->dev, "AFE_ADDA_IIR_COEF_04_03 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_IIR_COEF_06_05, &value);
> +	dev_info(afe->dev, "AFE_ADDA_IIR_COEF_06_05 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_IIR_COEF_08_07, &value);
> +	dev_info(afe->dev, "AFE_ADDA_IIR_COEF_08_07 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_IIR_COEF_10_09, &value);
> +	dev_info(afe->dev, "AFE_ADDA_IIR_COEF_10_09 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CON1, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CON2, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAC_MON, &value);
> +	dev_info(afe->dev, "AFE_DAC_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CON3, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CON4, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CON4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT0, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT6, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT8, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_DSP2_EN, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_DSP2_EN = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ0_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ0_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ6_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ6_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL4_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL4_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL4_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL4_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL4_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL4_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_END, &value);
> +	dev_info(afe->dev, "AFE_VUL4_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL12_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL12_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL12_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL12_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL12_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL12_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_END, &value);
> +	dev_info(afe->dev, "AFE_VUL12_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ3_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ3_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ4_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ4_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CON0, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_STATUS = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CLR, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CLR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT1, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT2, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_EN = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_MON2, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_MON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT5, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ1_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ1_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ2_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ2_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ5_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ5_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_DSP_EN, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_DSP_EN = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_SCP_EN, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_SCP_EN = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT7, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ7_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ7_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT3, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT4, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT11, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT11 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_APLL1_TUNER_CFG, &value);
> +	dev_info(afe->dev, "AFE_APLL1_TUNER_CFG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_APLL2_TUNER_CFG, &value);
> +	dev_info(afe->dev, "AFE_APLL2_TUNER_CFG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_MISS_CLR, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_MISS_CLR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN33, &value);
> +	dev_info(afe->dev, "AFE_CONN33 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT12, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN1_CON0, &value);
> +	dev_info(afe->dev, "AFE_GAIN1_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN1_CON1, &value);
> +	dev_info(afe->dev, "AFE_GAIN1_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN1_CON2, &value);
> +	dev_info(afe->dev, "AFE_GAIN1_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN1_CON3, &value);
> +	dev_info(afe->dev, "AFE_GAIN1_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN7, &value);
> +	dev_info(afe->dev, "AFE_CONN7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN1_CUR, &value);
> +	dev_info(afe->dev, "AFE_GAIN1_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN2_CON0, &value);
> +	dev_info(afe->dev, "AFE_GAIN2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN2_CON1, &value);
> +	dev_info(afe->dev, "AFE_GAIN2_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN2_CON2, &value);
> +	dev_info(afe->dev, "AFE_GAIN2_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN2_CON3, &value);
> +	dev_info(afe->dev, "AFE_GAIN2_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN8, &value);
> +	dev_info(afe->dev, "AFE_CONN8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GAIN2_CUR, &value);
> +	dev_info(afe->dev, "AFE_GAIN2_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN9, &value);
> +	dev_info(afe->dev, "AFE_CONN9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN10, &value);
> +	dev_info(afe->dev, "AFE_CONN10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN11, &value);
> +	dev_info(afe->dev, "AFE_CONN11 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN12, &value);
> +	dev_info(afe->dev, "AFE_CONN12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN13, &value);
> +	dev_info(afe->dev, "AFE_CONN13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN14, &value);
> +	dev_info(afe->dev, "AFE_CONN14 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN15, &value);
> +	dev_info(afe->dev, "AFE_CONN15 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN16, &value);
> +	dev_info(afe->dev, "AFE_CONN16 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN17, &value);
> +	dev_info(afe->dev, "AFE_CONN17 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN18, &value);
> +	dev_info(afe->dev, "AFE_CONN18 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN19, &value);
> +	dev_info(afe->dev, "AFE_CONN19 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN20, &value);
> +	dev_info(afe->dev, "AFE_CONN20 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN21, &value);
> +	dev_info(afe->dev, "AFE_CONN21 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN22, &value);
> +	dev_info(afe->dev, "AFE_CONN22 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN23, &value);
> +	dev_info(afe->dev, "AFE_CONN23 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN24, &value);
> +	dev_info(afe->dev, "AFE_CONN24 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_RS, &value);
> +	dev_info(afe->dev, "AFE_CONN_RS = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_DI, &value);
> +	dev_info(afe->dev, "AFE_CONN_DI = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN25, &value);
> +	dev_info(afe->dev, "AFE_CONN25 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN26, &value);
> +	dev_info(afe->dev, "AFE_CONN26 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN27, &value);
> +	dev_info(afe->dev, "AFE_CONN27 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN28, &value);
> +	dev_info(afe->dev, "AFE_CONN28 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN29, &value);
> +	dev_info(afe->dev, "AFE_CONN29 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN30, &value);
> +	dev_info(afe->dev, "AFE_CONN30 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN31, &value);
> +	dev_info(afe->dev, "AFE_CONN31 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN32, &value);
> +	dev_info(afe->dev, "AFE_CONN32 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SRAM_DELSEL_CON1, &value);
> +	dev_info(afe->dev, "AFE_SRAM_DELSEL_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN56, &value);
> +	dev_info(afe->dev, "AFE_CONN56 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN57, &value);
> +	dev_info(afe->dev, "AFE_CONN57 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN56_1, &value);
> +	dev_info(afe->dev, "AFE_CONN56_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN57_1, &value);
> +	dev_info(afe->dev, "AFE_CONN57_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, PCM_INTF_CON1, &value);
> +	dev_info(afe->dev, "PCM_INTF_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, PCM_INTF_CON2, &value);
> +	dev_info(afe->dev, "PCM_INTF_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, PCM2_INTF_CON, &value);
> +	dev_info(afe->dev, "PCM2_INTF_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN34, &value);
> +	dev_info(afe->dev, "AFE_CONN34 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_DBG_CON, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_DBG_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_DBG_MON0, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_DBG_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AUDIO_TOP_DBG_MON1, &value);
> +	dev_info(afe->dev, "AUDIO_TOP_DBG_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ8_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ8_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ11_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ11_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ12_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ12_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT9, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT10, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT13, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT14, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT14 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT15, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT15 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT16, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT16 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT17, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT17 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT18, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT18 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT19, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT19 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT20, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT20 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT21, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT21 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT22, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT22 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT23, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT23 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT24, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT24 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT25, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT25 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ_MCU_CNT26, &value);
> +	dev_info(afe->dev, "AFE_IRQ_MCU_CNT26 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ9_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ9_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ10_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ10_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ13_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ13_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ14_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ14_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ15_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ15_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ16_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ16_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ17_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ17_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ18_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ18_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ19_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ19_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ20_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ20_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ21_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ21_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ22_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ22_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ23_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ23_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ24_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ24_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ25_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ25_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ26_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ26_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_IRQ31_MCU_CNT_MON, &value);
> +	dev_info(afe->dev, "AFE_IRQ31_MCU_CNT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG0, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG1, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG2, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG3, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG4, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG5, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG6, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG7, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG8, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG9, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG10, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG11, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG11 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG12, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG13, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG14, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG14 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL_REG15, &value);
> +	dev_info(afe->dev, "AFE_GENERAL_REG15 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CBIP_CFG0, &value);
> +	dev_info(afe->dev, "AFE_CBIP_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CBIP_MON0, &value);
> +	dev_info(afe->dev, "AFE_CBIP_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CBIP_SLV_MUX_MON0, &value);
> +	dev_info(afe->dev, "AFE_CBIP_SLV_MUX_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CBIP_SLV_DECODER_MON0, &value);
> +	dev_info(afe->dev, "AFE_CBIP_SLV_DECODER_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_MON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_CON0, &value);
> +	dev_info(afe->dev, "AFE_AWB_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_BASE, &value);
> +	dev_info(afe->dev, "AFE_AWB_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_CUR, &value);
> +	dev_info(afe->dev, "AFE_AWB_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_END, &value);
> +	dev_info(afe->dev, "AFE_AWB_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_CON0, &value);
> +	dev_info(afe->dev, "AFE_AWB2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB2_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_BASE, &value);
> +	dev_info(afe->dev, "AFE_AWB2_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB2_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_CUR, &value);
> +	dev_info(afe->dev, "AFE_AWB2_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_AWB2_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_END, &value);
> +	dev_info(afe->dev, "AFE_AWB2_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_CON0, &value);
> +	dev_info(afe->dev, "AFE_DAI_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_BASE, &value);
> +	dev_info(afe->dev, "AFE_DAI_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_CUR, &value);
> +	dev_info(afe->dev, "AFE_DAI_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_END, &value);
> +	dev_info(afe->dev, "AFE_DAI_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_CON0, &value);
> +	dev_info(afe->dev, "AFE_DAI2_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI2_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_BASE, &value);
> +	dev_info(afe->dev, "AFE_DAI2_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI2_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_CUR, &value);
> +	dev_info(afe->dev, "AFE_DAI2_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DAI2_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_END, &value);
> +	dev_info(afe->dev, "AFE_DAI2_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MEMIF_CON0, &value);
> +	dev_info(afe->dev, "AFE_MEMIF_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN0_1, &value);
> +	dev_info(afe->dev, "AFE_CONN0_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN1_1, &value);
> +	dev_info(afe->dev, "AFE_CONN1_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN2_1, &value);
> +	dev_info(afe->dev, "AFE_CONN2_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN3_1, &value);
> +	dev_info(afe->dev, "AFE_CONN3_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN4_1, &value);
> +	dev_info(afe->dev, "AFE_CONN4_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN5_1, &value);
> +	dev_info(afe->dev, "AFE_CONN5_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN6_1, &value);
> +	dev_info(afe->dev, "AFE_CONN6_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN7_1, &value);
> +	dev_info(afe->dev, "AFE_CONN7_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN8_1, &value);
> +	dev_info(afe->dev, "AFE_CONN8_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN9_1, &value);
> +	dev_info(afe->dev, "AFE_CONN9_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN10_1, &value);
> +	dev_info(afe->dev, "AFE_CONN10_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN11_1, &value);
> +	dev_info(afe->dev, "AFE_CONN11_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN12_1, &value);
> +	dev_info(afe->dev, "AFE_CONN12_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN13_1, &value);
> +	dev_info(afe->dev, "AFE_CONN13_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN14_1, &value);
> +	dev_info(afe->dev, "AFE_CONN14_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN15_1, &value);
> +	dev_info(afe->dev, "AFE_CONN15_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN16_1, &value);
> +	dev_info(afe->dev, "AFE_CONN16_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN17_1, &value);
> +	dev_info(afe->dev, "AFE_CONN17_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN18_1, &value);
> +	dev_info(afe->dev, "AFE_CONN18_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN19_1, &value);
> +	dev_info(afe->dev, "AFE_CONN19_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN20_1, &value);
> +	dev_info(afe->dev, "AFE_CONN20_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN21_1, &value);
> +	dev_info(afe->dev, "AFE_CONN21_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN22_1, &value);
> +	dev_info(afe->dev, "AFE_CONN22_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN23_1, &value);
> +	dev_info(afe->dev, "AFE_CONN23_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN24_1, &value);
> +	dev_info(afe->dev, "AFE_CONN24_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN25_1, &value);
> +	dev_info(afe->dev, "AFE_CONN25_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN26_1, &value);
> +	dev_info(afe->dev, "AFE_CONN26_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN27_1, &value);
> +	dev_info(afe->dev, "AFE_CONN27_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN28_1, &value);
> +	dev_info(afe->dev, "AFE_CONN28_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN29_1, &value);
> +	dev_info(afe->dev, "AFE_CONN29_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN30_1, &value);
> +	dev_info(afe->dev, "AFE_CONN30_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN31_1, &value);
> +	dev_info(afe->dev, "AFE_CONN31_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN32_1, &value);
> +	dev_info(afe->dev, "AFE_CONN32_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN33_1, &value);
> +	dev_info(afe->dev, "AFE_CONN33_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN34_1, &value);
> +	dev_info(afe->dev, "AFE_CONN34_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_RS_1, &value);
> +	dev_info(afe->dev, "AFE_CONN_RS_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_DI_1, &value);
> +	dev_info(afe->dev, "AFE_CONN_DI_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_24BIT_1, &value);
> +	dev_info(afe->dev, "AFE_CONN_24BIT_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN_REG, &value);
> +	dev_info(afe->dev, "AFE_CONN_REG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN35, &value);
> +	dev_info(afe->dev, "AFE_CONN35 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN36, &value);
> +	dev_info(afe->dev, "AFE_CONN36 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN37, &value);
> +	dev_info(afe->dev, "AFE_CONN37 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN38, &value);
> +	dev_info(afe->dev, "AFE_CONN38 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN35_1, &value);
> +	dev_info(afe->dev, "AFE_CONN35_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN36_1, &value);
> +	dev_info(afe->dev, "AFE_CONN36_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN37_1, &value);
> +	dev_info(afe->dev, "AFE_CONN37_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN38_1, &value);
> +	dev_info(afe->dev, "AFE_CONN38_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN39, &value);
> +	dev_info(afe->dev, "AFE_CONN39 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN40, &value);
> +	dev_info(afe->dev, "AFE_CONN40 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN41, &value);
> +	dev_info(afe->dev, "AFE_CONN41 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN42, &value);
> +	dev_info(afe->dev, "AFE_CONN42 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN39_1, &value);
> +	dev_info(afe->dev, "AFE_CONN39_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN40_1, &value);
> +	dev_info(afe->dev, "AFE_CONN40_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN41_1, &value);
> +	dev_info(afe->dev, "AFE_CONN41_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN42_1, &value);
> +	dev_info(afe->dev, "AFE_CONN42_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_I2S_CON4, &value);
> +	dev_info(afe->dev, "AFE_I2S_CON4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_TOP_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_TOP_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_UL_SRC_CON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_UL_SRC_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_UL_SRC_CON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_UL_SRC_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_SRC_DEBUG, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_SRC_DEBUG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_SRC_DEBUG_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_SRC_DEBUG_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_02_01, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_02_01 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_04_03, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_04_03 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_06_05, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_06_05 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_08_07, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_08_07 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_10_09, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_10_09 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_12_11, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_12_11 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_14_13, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_14_13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_16_15, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_16_15 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_18_17, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_18_17 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_20_19, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_20_19 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_22_21, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_22_21 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_24_23, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_24_23 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_26_25, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_26_25 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_28_27, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_28_27 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_ULCF_CFG_30_29, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_ULCF_CFG_30_29 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADD6A_UL_SRC_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADD6A_UL_SRC_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_UL_SRC_MON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_UL_SRC_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN43, &value);
> +	dev_info(afe->dev, "AFE_CONN43 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN43_1, &value);
> +	dev_info(afe->dev, "AFE_CONN43_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_CON0, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_BASE, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_CUR, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_END, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_AWB_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_AWB_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL12_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL12_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL12_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL2_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL2_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL2_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI_DATA_MON, &value);
> +	dev_info(afe->dev, "AFE_DAI_DATA_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_MOD_DAI_DATA_MON, &value);
> +	dev_info(afe->dev, "AFE_MOD_DAI_DATA_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DAI2_DATA_MON, &value);
> +	dev_info(afe->dev, "AFE_DAI2_DATA_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_AWB2_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AWB2_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_AWB2_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL3_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL3_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL3_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL4_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL4_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL4_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL5_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL5_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL6_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_VUL6_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL1_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL1_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL1_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL2_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL2_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL2_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_RCH1_MON, &value);
> +	dev_info(afe->dev, "AFE_DL12_RCH1_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_LCH1_MON, &value);
> +	dev_info(afe->dev, "AFE_DL12_LCH1_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_RCH2_MON, &value);
> +	dev_info(afe->dev, "AFE_DL12_RCH2_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL12_LCH2_MON, &value);
> +	dev_info(afe->dev, "AFE_DL12_LCH2_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL3_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL3_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL3_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL4_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL4_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL4_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL5_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL5_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL6_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL6_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL7_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL7_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL8_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_DL8_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL5_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL5_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL5_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL5_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL5_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL5_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL5_END, &value);
> +	dev_info(afe->dev, "AFE_VUL5_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_CON0, &value);
> +	dev_info(afe->dev, "AFE_VUL6_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL6_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_BASE, &value);
> +	dev_info(afe->dev, "AFE_VUL6_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL6_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_CUR, &value);
> +	dev_info(afe->dev, "AFE_VUL6_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_VUL6_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_VUL6_END, &value);
> +	dev_info(afe->dev, "AFE_VUL6_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_DCCOMP_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_TEST, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_TEST = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_DC_COMP_CFG0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_DC_COMP_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_DC_COMP_CFG1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_DC_COMP_CFG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_FIFO_MON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_FIFO_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SRC_LCH_MON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SRC_LCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SRC_RCH_MON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SRC_RCH_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_OUT_MON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_OUT_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_DITHER_CON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_DITHER_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_SDM_AUTO_RESET_CON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_SDM_AUTO_RESET_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONNSYS_I2S_CON, &value);
> +	dev_info(afe->dev, "AFE_CONNSYS_I2S_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONNSYS_I2S_MON, &value);
> +	dev_info(afe->dev, "AFE_CONNSYS_I2S_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON0, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON1, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON2, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON3, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON4, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON5, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON6, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON7, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON8, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON9, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON10, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON12, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ASRC_2CH_CON13, &value);
> +	dev_info(afe->dev, "AFE_ASRC_2CH_CON13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_IIR_COEF_02_01, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_IIR_COEF_02_01 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_IIR_COEF_04_03, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_IIR_COEF_04_03 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_IIR_COEF_06_05, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_IIR_COEF_06_05 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_IIR_COEF_08_07, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_IIR_COEF_08_07 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_IIR_COEF_10_09, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_IIR_COEF_10_09 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_PROT_SIDEBAND, &value);
> +	dev_info(afe->dev, "AFE_SE_PROT_SIDEBAND = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_DOMAIN_SIDEBAND0, &value);
> +	dev_info(afe->dev, "AFE_SE_DOMAIN_SIDEBAND0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_PREDIS_CON2, &value);
> +	dev_info(afe->dev, "AFE_ADDA_PREDIS_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_PREDIS_CON3, &value);
> +	dev_info(afe->dev, "AFE_ADDA_PREDIS_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_DOMAIN_SIDEBAND1, &value);
> +	dev_info(afe->dev, "AFE_SE_DOMAIN_SIDEBAND1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_DOMAIN_SIDEBAND2, &value);
> +	dev_info(afe->dev, "AFE_SE_DOMAIN_SIDEBAND2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_DOMAIN_SIDEBAND3, &value);
> +	dev_info(afe->dev, "AFE_SE_DOMAIN_SIDEBAND3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN44, &value);
> +	dev_info(afe->dev, "AFE_CONN44 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN45, &value);
> +	dev_info(afe->dev, "AFE_CONN45 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN46, &value);
> +	dev_info(afe->dev, "AFE_CONN46 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN47, &value);
> +	dev_info(afe->dev, "AFE_CONN47 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN44_1, &value);
> +	dev_info(afe->dev, "AFE_CONN44_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN45_1, &value);
> +	dev_info(afe->dev, "AFE_CONN45_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN46_1, &value);
> +	dev_info(afe->dev, "AFE_CONN46_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN47_1, &value);
> +	dev_info(afe->dev, "AFE_CONN47_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_HD_ENGEN_ENABLE, &value);
> +	dev_info(afe->dev, "AFE_HD_ENGEN_ENABLE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_DL_NLE_FIFO_MON, &value);
> +	dev_info(afe->dev, "AFE_ADDA_DL_NLE_FIFO_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_CFG0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_SYNCWORD_CFG, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_SYNCWORD_CFG = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_RX_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_RX_CFG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_RX_CFG2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_MON0, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA_MTKAIF_MON1, &value);
> +	dev_info(afe->dev, "AFE_ADDA_MTKAIF_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_AUD_PAD_TOP, &value);
> +	dev_info(afe->dev, "AFE_AUD_PAD_TOP = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_R_CFG0, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_R_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_R_CFG1, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_R_CFG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_L_CFG0, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_L_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_L_CFG1, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_L_CFG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_R_MON0, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_R_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_R_MON1, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_R_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_R_MON2, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_R_MON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_L_MON0, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_L_MON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_L_MON1, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_L_MON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_L_MON2, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_L_MON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL_NLE_GAIN_CFG0, &value);
> +	dev_info(afe->dev, "AFE_DL_NLE_GAIN_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG0, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_RX_CFG0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG1, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_RX_CFG1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, &value);
> +	dev_info(afe->dev, "AFE_ADDA6_MTKAIF_RX_CFG2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON0, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON1, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON2, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON3, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON4, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON5, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON6, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON7, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON8, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON9, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON10, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON12, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL1_ASRC_2CH_CON13, &value);
> +	dev_info(afe->dev, "AFE_GENERAL1_ASRC_2CH_CON13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, GENERAL_ASRC_MODE, &value);
> +	dev_info(afe->dev, "GENERAL_ASRC_MODE = 0x%x\n", value);
> +	regmap_read(afe->regmap, GENERAL_ASRC_EN_ON, &value);
> +	dev_info(afe->dev, "GENERAL_ASRC_EN_ON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN48, &value);
> +	dev_info(afe->dev, "AFE_CONN48 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN49, &value);
> +	dev_info(afe->dev, "AFE_CONN49 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN50, &value);
> +	dev_info(afe->dev, "AFE_CONN50 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN51, &value);
> +	dev_info(afe->dev, "AFE_CONN51 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN52, &value);
> +	dev_info(afe->dev, "AFE_CONN52 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN53, &value);
> +	dev_info(afe->dev, "AFE_CONN53 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN54, &value);
> +	dev_info(afe->dev, "AFE_CONN54 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN55, &value);
> +	dev_info(afe->dev, "AFE_CONN55 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN48_1, &value);
> +	dev_info(afe->dev, "AFE_CONN48_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN49_1, &value);
> +	dev_info(afe->dev, "AFE_CONN49_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN50_1, &value);
> +	dev_info(afe->dev, "AFE_CONN50_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN51_1, &value);
> +	dev_info(afe->dev, "AFE_CONN51_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN52_1, &value);
> +	dev_info(afe->dev, "AFE_CONN52_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN53_1, &value);
> +	dev_info(afe->dev, "AFE_CONN53_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN54_1, &value);
> +	dev_info(afe->dev, "AFE_CONN54_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_CONN55_1, &value);
> +	dev_info(afe->dev, "AFE_CONN55_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON0, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON1, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON2, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON3, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON4, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON5, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON6, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON7, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON8, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON9, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON10, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON12, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_GENERAL2_ASRC_2CH_CON13, &value);
> +	dev_info(afe->dev, "AFE_GENERAL2_ASRC_2CH_CON13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL5_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL5_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL5_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL5_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL5_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL5_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL5_END, &value);
> +	dev_info(afe->dev, "AFE_DL5_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL6_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL6_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL6_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL6_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL6_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL6_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL6_END, &value);
> +	dev_info(afe->dev, "AFE_DL6_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL7_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL7_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL7_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL7_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL7_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL7_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL7_END, &value);
> +	dev_info(afe->dev, "AFE_DL7_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_CON0, &value);
> +	dev_info(afe->dev, "AFE_DL8_CON0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_BASE_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL8_BASE_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_BASE, &value);
> +	dev_info(afe->dev, "AFE_DL8_BASE = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_CUR_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL8_CUR_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_CUR, &value);
> +	dev_info(afe->dev, "AFE_DL8_CUR = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_END_MSB, &value);
> +	dev_info(afe->dev, "AFE_DL8_END_MSB = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DL8_END, &value);
> +	dev_info(afe->dev, "AFE_DL8_END = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SE_SECURE_CON, &value);
> +	dev_info(afe->dev, "AFE_SE_SECURE_CON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_PROT_SIDEBAND_MON, &value);
> +	dev_info(afe->dev, "AFE_PROT_SIDEBAND_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DOMAIN_SIDEBAND0_MON, &value);
> +	dev_info(afe->dev, "AFE_DOMAIN_SIDEBAND0_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DOMAIN_SIDEBAND1_MON, &value);
> +	dev_info(afe->dev, "AFE_DOMAIN_SIDEBAND1_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DOMAIN_SIDEBAND2_MON, &value);
> +	dev_info(afe->dev, "AFE_DOMAIN_SIDEBAND2_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_DOMAIN_SIDEBAND3_MON, &value);
> +	dev_info(afe->dev, "AFE_DOMAIN_SIDEBAND3_MON = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN0, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN0 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN2, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN2 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN3, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN3 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN4, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN4 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN5, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN5 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN6, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN6 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN7, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN7 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN8, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN8 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN9, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN9 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN10, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN10 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN11, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN11 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN12, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN12 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN13, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN13 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN14, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN14 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN15, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN15 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN16, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN16 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN17, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN17 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN18, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN18 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN19, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN19 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN20, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN20 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN21, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN21 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN22, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN22 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN23, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN23 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN24, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN24 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN25, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN25 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN26, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN26 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN27, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN27 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN28, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN28 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN29, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN29 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN30, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN30 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN31, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN31 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN32, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN32 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN33, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN33 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN34, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN34 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN35, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN35 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN36, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN36 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN37, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN37 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN38, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN38 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN39, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN39 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN40, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN40 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN41, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN41 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN42, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN42 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN43, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN43 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN44, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN44 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN45, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN45 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN46, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN46 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN47, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN47 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN48, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN48 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN49, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN49 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN50, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN50 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN51, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN51 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN52, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN52 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN53, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN53 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN54, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN54 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN55, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN55 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN56, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN56 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN57, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN57 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN0_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN0_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN1_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN1_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN2_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN2_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN3_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN3_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN4_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN4_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN5_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN5_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN6_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN6_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN7_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN7_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN8_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN8_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN9_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN9_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN10_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN10_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN11_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN11_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN12_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN12_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN13_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN13_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN14_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN14_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN15_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN15_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN16_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN16_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN17_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN17_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN18_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN18_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN19_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN19_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN20_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN20_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN21_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN21_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN22_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN22_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN23_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN23_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN24_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN24_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN25_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN25_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN26_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN26_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN27_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN27_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN28_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN28_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN29_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN29_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN30_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN30_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN31_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN31_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN32_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN32_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN33_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN33_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN34_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN34_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN35_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN35_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN36_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN36_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN37_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN37_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN38_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN38_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN39_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN39_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN40_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN40_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN41_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN41_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN42_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN42_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN43_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN43_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN44_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN44_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN45_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN45_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN46_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN46_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN47_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN47_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN48_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN48_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN49_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN49_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN50_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN50_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN51_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN51_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN52_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN52_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN53_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN53_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN54_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN54_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN55_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN55_1 = 0x%x\n", value);
> +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN56_1, &value);
> +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN56_1 = 0x%x\n", value);
> +
> +	return 0;
> +}
> +
> +static const struct soc_enum mt8186_afe_misc_enum[] = {
> +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_afe_off_on_str),
> +			    mt8186_afe_off_on_str),
> +};
> +
> +static const struct snd_kcontrol_new mt8186_afe_debug_controls[] = {
> +	SOC_ENUM_EXT("Audio_Debug_Setting", mt8186_afe_misc_enum[0],
> +		     mt8186_afe_debug_get, mt8186_afe_debug_set),
> +};
> +
> +int mt8186_add_misc_control(struct snd_soc_component *component)
> +{
> +	snd_soc_add_component_controls(component,
> +				       mt8186_afe_sgen_controls,
> +				       ARRAY_SIZE(mt8186_afe_sgen_controls));
> +
> +	snd_soc_add_component_controls(component,
> +				       mt8186_afe_debug_controls,
> +				       ARRAY_SIZE(mt8186_afe_debug_controls));
> +
> +	return 0;
> +}
> diff --git a/sound/soc/mediatek/mt8186/mt8186-reg.h b/sound/soc/mediatek/mt8186/mt8186-reg.h
> new file mode 100644
> index 000000000000..34bb28188fca
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-reg.h
> @@ -0,0 +1,3433 @@
> +/* SPDX-License-Identifier: GPL-2.0
> + *
> + * mt8186-reg.h  --  Mediatek 8186 audio driver reg definition
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> + */
> +
> +#ifndef _MT8186_REG_H_
> +#define _MT8186_REG_H_
> +
> +/* reg bit enum */
> +enum {
> +	MT8186_MEMIF_PBUF_SIZE_32_BYTES,
> +	MT8186_MEMIF_PBUF_SIZE_64_BYTES,
> +	MT8186_MEMIF_PBUF_SIZE_128_BYTES,
> +	MT8186_MEMIF_PBUF_SIZE_256_BYTES,
> +	MT8186_MEMIF_PBUF_SIZE_NUM,
> +};
> +
> +/*****************************************************************************
> + *                  R E G I S T E R       D E F I N I T I O N
> + *****************************************************************************/
> +/* AUDIO_TOP_CON0 */
> +#define RESERVED_SFT					31
> +#define RESERVED_MASK					0x1
> +#define RESERVED_MASK_SFT				(0x1 << 31)

BIT() and GENMASK() macros please!

Regards,
Angelo
AngeloGioacchino Del Regno Feb. 18, 2022, 2:54 p.m. UTC | #12
Il 17/02/22 14:42, Jiaxin Yu ha scritto:
> This patch adds support for mt8186 board with mt6366, da7219 and max98357.
> 
> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> ---
>   .../mt8186/mt8186-mt6366-da7219-max98357.c    | 910 ++++++++++++++++++
>   1 file changed, 910 insertions(+)
>   create mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
> 
> diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
> new file mode 100644
> index 000000000000..6ba53b8d1e46
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
> @@ -0,0 +1,910 @@
> +// SPDX-License-Identifier: GPL-2.0
> +//
> +// mt8186-mt6366-da7219-max98357.c
> +//	--  MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver
> +//
> +// Copyright (c) 2022 MediaTek Inc.
> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> +//
> +
> +#include <linux/input.h>
> +#include <linux/module.h>
> +#include <linux/pm_runtime.h>
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +
> +#include "../../codecs/da7219-aad.h"
> +#include "../../codecs/da7219.h"
> +#include "../../codecs/mt6358.h"
> +#include "../common/mtk-afe-platform-driver.h"
> +#include "mt8186-afe-common.h"
> +#include "mt8186-afe-clk.h"
> +#include "mt8186-afe-gpio.h"
> +
> +#define DA7219_CODEC_DAI "da7219-hifi"
> +#define DA7219_DEV_NAME "da7219.5-001a"
> +
> +struct mt8186_mt6366_da7219_max98357_priv {
> +	struct snd_soc_jack headset_jack, hdmi_jack;
> +};
> +
> +static struct snd_soc_codec_conf mt6366_codec_conf[] = {
> +	{
> +		.dlc = COMP_CODEC_CONF("mt6358-sound"),
> +		.name_prefix = "Mt6366",
> +	},
> +};
> +
> +static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct mt8186_mt6366_da7219_max98357_priv *priv =
> +		snd_soc_card_get_drvdata(rtd->card);
> +	struct snd_soc_jack *jack = &priv->headset_jack;
> +	struct snd_soc_component *cmpnt_codec =
> +		asoc_rtd_to_codec(rtd, 0)->component;
> +	int ret;
> +
> +	/* Enable Headset and 4 Buttons Jack detection */
> +	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
> +				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
> +				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
> +				    SND_JACK_BTN_3 | SND_JACK_LINEOUT,
> +				    jack, NULL, 0);
> +	if (ret) {
> +		dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
> +
> +	da7219_aad_jack_det(cmpnt_codec, &priv->headset_jack);
> +
> +	return 0;
> +}
> +
> +static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream *substream,
> +				       struct snd_pcm_hw_params *params)
> +{
> +	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
> +	struct snd_soc_dai *codec_dai;
> +	unsigned int rate = params_rate(params);
> +	unsigned int mclk_fs_ratio = 256;
> +	unsigned int mclk_fs = rate * mclk_fs_ratio;
> +	unsigned int freq;
> +	int ret = 0, j;
> +
> +	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
> +				     mclk_fs, SND_SOC_CLOCK_OUT);
> +	if (ret < 0)
> +		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");

Does it really make sense to go on after this failure?

> +
> +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
> +		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
> +			ret = snd_soc_dai_set_sysclk(codec_dai,
> +						     DA7219_CLKSRC_MCLK,
> +						     mclk_fs,
> +						     SND_SOC_CLOCK_IN);
> +			if (ret < 0)
> +				dev_err(rtd->dev, "failed to set sysclk\n");
> +

I think that going on past this wouldn't make sense as well, as it may result
in unexpected behavior... just return a failure here

> +			if ((rate % 8000) == 0)
> +				freq = DA7219_PLL_FREQ_OUT_98304;
> +			else
> +				freq = DA7219_PLL_FREQ_OUT_90316;
> +
> +			ret = snd_soc_dai_set_pll(codec_dai, 0,
> +						  DA7219_SYSCLK_PLL_SRM,
> +						  0, freq);
> +			if (ret)
> +				dev_err(rtd->dev, "failed to start PLL: %d\n",
> +					ret);

and here

> +		}
> +	}
> +

So, you've covered all failure cases already, for which, you can simply
return 0 here.

> +	return ret;
> +}
> +
> +static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream *substream)
> +{
> +	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
> +	struct snd_soc_dai *codec_dai;
> +	int ret = 0, j;
> +
> +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
> +		if (!strcmp(codec_dai->component->name, DA7219_DEV_NAME)) {
> +			ret = snd_soc_dai_set_pll(codec_dai,
> +						  0, DA7219_SYSCLK_MCLK, 0, 0);
> +			if (ret < 0) {
> +				dev_err(rtd->dev, "failed to stop PLL: %d\n",
> +					ret);
> +				break;
> +			}
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
> +	.hw_params = mt8186_da7219_i2s_hw_params,
> +	.hw_free = mt8186_da7219_i2s_hw_free,
> +};
> +
> +static int mt8186_mt6366_hdmi_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_soc_component *cmpnt_codec =
> +		asoc_rtd_to_codec(rtd, 0)->component;
> +	struct mt8186_mt6366_da7219_max98357_priv *priv =
> +		snd_soc_card_get_drvdata(rtd->card);
> +	int ret;
> +
> +	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
> +				    &priv->hdmi_jack, NULL, 0);
> +	if (ret) {
> +		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL);
> +}
> +
> +static int mt8186_mt6366_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_soc_component *cmpnt_afe =
> +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> +	struct snd_soc_component *cmpnt_codec =
> +		asoc_rtd_to_codec(rtd, 0)->component;
> +	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> +	struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
> +	int ret;
> +
> +	/* set mtkaif protocol */
> +	mt6358_set_mtkaif_protocol(cmpnt_codec,
> +				   MT6358_MTKAIF_PROTOCOL_1);
> +	afe_priv->mtkaif_protocol = MT6358_MTKAIF_PROTOCOL_1;
> +
> +	ret = snd_soc_dapm_sync(dapm);
> +	if (ret) {
> +		dev_info(rtd->dev, "failed to snd_soc_dapm_sync\n");

dev_err()

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> +				      struct snd_pcm_hw_params *params)
> +{
> +	struct snd_interval *channels = hw_param_interval(params,
> +		SNDRV_PCM_HW_PARAM_CHANNELS);
> +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
> +

dev_dbg()

> +	/* fix BE i2s channel to 2 channel */
> +	channels->min = 2;
> +	channels->max = 2;
> +
> +	/* fix BE i2s format to S32_LE, clean param mask first */
> +	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
> +			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
> +
> +	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
> +
> +	return 0;
> +}
> +
> +static int mt8186_hdmi_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> +					   struct snd_pcm_hw_params *params)
> +{
> +	struct snd_interval *channels = hw_param_interval(params,
> +		SNDRV_PCM_HW_PARAM_CHANNELS);
> +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
> +

dev_dbg()

> +	/* fix BE i2s channel to 2 channel */
> +	channels->min = 2;
> +	channels->max = 2;
> +
> +	/* fix BE i2s format to S24_LE, clean param mask first */
> +	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
> +			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
> +
> +	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
> +
> +	return 0;
> +}

Besides, I would do the following instead:

static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,

				  struct snd_pcm_hw_params *params,

				  snd_pcm_format_t fmt)

{

	struct snd_interval *channels = hw_param_interval(params,

		SNDRV_PCM_HW_PARAM_CHANNELS);

	dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__);



	/* fix BE i2s channel to 2 channel */

	channels->min = 2;

	channels->max = 2;



	/* fix BE i2s format to S32_LE, clean param mask first */

	snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),

			     0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);



	params_set_format(params, fmt);



	return 0;

}



static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,

				      struct snd_pcm_hw_params *params)

{

	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE);

}



static int mt8186_hdmi_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,

					   struct snd_pcm_hw_params *params)

{

	return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE);

}

... this reduces code duplication!

> +
> +/* FE */
> +SND_SOC_DAILINK_DEFS(playback1,
> +		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
> +		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
> +		     DAILINK_COMP_ARRAY(COMP_EMPTY()));


..snip..

> +static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev)
> +{
> +	struct snd_soc_card *card = &mt8186_mt6366_da7219_max98357_soc_card;
> +	struct snd_soc_dai_link *dai_link;
> +	struct mt8186_mt6366_da7219_max98357_priv *priv;
> +	struct device_node *platform_node, *hdmi_codec;
> +	int ret, i;
> +
> +	dev_info(&pdev->dev, "%s(), ++\n", __func__);
> +
> +	card->dev = &pdev->dev;
> +
> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> +	if (!priv)
> +		return -ENOMEM;
> +
> +	platform_node = of_parse_phandle(pdev->dev.of_node,
> +					 "mediatek,platform", 0);
> +	if (!platform_node) {
> +		dev_info(&pdev->dev,
> +			 "Property 'platform' missing or invalid\n");

	if (!platform_node)
		return dev_err_probe(&pdev->dev, -EINVAL,
				    "mediatek,platform missing or invalid\n");

> +		return -EINVAL;
> +	}
> +
> +	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
> +				      "mediatek,hdmi-codec", 0);
> +	if (!hdmi_codec) {
> +		dev_info(&pdev->dev,
> +			 "Property 'hdmi' missing or invalid\n");

dev_err()

> +		return -EINVAL;
> +	}
> +
> +	for_each_card_prelinks(card, i, dai_link) {
> +		if (dai_link->platforms->name)
> +			continue;
> +
> +		if (hdmi_codec && strcmp(dai_link->name, "I2S3") == 0) {
> +			dai_link->codecs->of_node = hdmi_codec;
> +			dai_link->ignore = 0;
> +		}
> +
> +		dai_link->platforms->of_node = platform_node;
> +	}
> +
> +	snd_soc_card_set_drvdata(card, priv);
> +
> +	/* init gpio */
> +	ret = mt8186_afe_gpio_init(&pdev->dev);
> +	if (ret)
> +		dev_info(&pdev->dev, "init gpio error\n");

dev_err() and goto end;

> +
> +	dev_info(&pdev->dev, "%s(), devm_snd_soc_register_card\n", __func__);
> +	ret = devm_snd_soc_register_card(&pdev->dev, card);
> +	if (ret)
> +		dev_info(&pdev->dev, "%s snd_soc_register_card fail %d\n",
> +			 __func__, ret);

dev_err_probe()

end:

> +	of_node_put(platform_node);
> +	of_node_put(hdmi_codec);
> +
> +	return ret;
> +}
> +
> +#if IS_ENABLED(CONFIG_OF)
> +static const struct of_device_id mt8186_mt6366_da7219_max98357_dt_match[] = {
> +	{.compatible = "mediatek,mt8186_mt6366_da7219_max98357_sound",},
> +	{}
> +};
> +#endif
> +
> +static struct platform_driver mt8186_mt6366_da7219_max98357_driver = {
> +	.driver = {
> +		.name = "mt8186_mt6366_da7219_max98357",
> +#if IS_ENABLED(CONFIG_OF)
> +		.of_match_table = mt8186_mt6366_da7219_max98357_dt_match,
> +#endif
> +		.pm = &snd_soc_pm_ops,
> +	},
> +	.probe = mt8186_mt6366_da7219_max98357_dev_probe,
> +};
> +
> +module_platform_driver(mt8186_mt6366_da7219_max98357_driver);
> +
> +/* Module information */
> +MODULE_DESCRIPTION("MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver");
> +MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("mt8186_mt6366_da7219_max98357 soc card");
Jiaxin Yu (俞家鑫) March 3, 2022, 2:10 p.m. UTC | #13
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch adds mt8186 tdm dai driver.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 713
> > +++++++++++++++++++++
> >   1 file changed, 713 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > new file mode 100644
> > index 000000000000..28dd3661f0e0
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > @@ -0,0 +1,713 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio DAI TDM Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/regmap.h>
> > +#include <sound/pcm_params.h>
> > +
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-gpio.h"
> > +#include "mt8186-interconnection.h"
> > +
> > +#define TDM_HD_EN_W_NAME "TDM_HD_EN"
> > +#define TDM_MCLK_EN_W_NAME "TDM_MCLK_EN"
> > +#define MTK_AFE_TDM_KCONTROL_NAME "TDM_HD_Mux"
> > +
> > +struct mtk_afe_tdm_priv {
> > +	unsigned int id;
> > +	unsigned int rate; /* for determine which apll to use */
> > +	unsigned int bck_invert;
> > +	unsigned int lck_invert;
> > +	unsigned int lrck_width;
> > +	unsigned int mclk_id;
> > +	unsigned int mclk_multiple; /* according to sample rate */
> > +	unsigned int mclk_rate;
> > +	unsigned int mclk_apll;
> > +	unsigned int tdm_mode;
> > +	unsigned int data_mode;
> > +	unsigned int slave_mode;
> > +	unsigned int low_jitter_en;
> > +};
> > +
> > +enum {
> > +	TDM_IN_I2S = 0,
> > +	TDM_IN_LJ = 1,
> > +	TDM_IN_RJ = 2,
> > +	TDM_IN_DSP_A = 4,
> > +	TDM_IN_DSP_B = 5,
> > +};
> > +
> > +enum {
> > +	TDM_DATA_ONE_PIN = 0,
> > +	TDM_DATA_MULTI_PIN,
> > +};
> > +
> > +enum {
> > +	TDM_BCK_NON_INV = 0,
> > +	TDM_BCK_INV = 1,
> > +};
> > +
> > +enum {
> > +	TDM_LCK_NON_INV = 0,
> > +	TDM_LCK_INV = 1,
> > +};
> > +
> > +static unsigned int get_tdm_lrck_width(snd_pcm_format_t format,
> > +				       unsigned int mode)
> > +{
> > +	if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B)
> > +		return 0;
> > +	else
> 
> Drop the "else"
> 
> > +		return snd_pcm_format_physical_width(format) - 1;
> > +}
> > +
> > +static unsigned int get_tdm_ch_fixup(unsigned int channels)
> > +{
> > +	if (channels > 4)
> > +		return 8;
> > +	else if (channels > 2)
> > +		return 4;
> > +	else
> 
> Same here
> 
> > +		return 2;
> > +}
> > +
> > +static unsigned int get_tdm_ch_per_sdata(unsigned int mode,
> > +					 unsigned int channels)
> > +{
> > +	if (mode == TDM_IN_DSP_A || mode == TDM_IN_DSP_B)
> > +		return get_tdm_ch_fixup(channels);
> > +	else
> 
> ...and same here
> 
> > +		return 2;
> > +}
> > +
> > +enum {
> > +	SUPPLY_SEQ_APLL,
> > +	SUPPLY_SEQ_TDM_MCK_EN,
> > +	SUPPLY_SEQ_TDM_HD_EN,
> > +	SUPPLY_SEQ_TDM_EN,
> > +};
> > +
> > +static int get_tdm_id_by_name(const char *name)
> > +{
> > +	return MT8186_DAI_TDM_IN;
> > +}
> > +
> > +static int mtk_tdm_en_event(struct snd_soc_dapm_widget *w,
> > +			    struct snd_kcontrol *kcontrol,
> > +			    int event)
> > +{
> > +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int dai_id = get_tdm_id_by_name(w->name);
> > +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> > +
> > +	if (!tdm_priv) {
> > +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
> > +		__func__, w->name, event);
> > +
> > +	switch (event) {
> > +	case SND_SOC_DAPM_PRE_PMU:
> > +		mt8186_afe_gpio_request(afe->dev, true, tdm_priv->id,
> > 0);
> > +		break;
> > +	case SND_SOC_DAPM_POST_PMD:
> > +		mt8186_afe_gpio_request(afe->dev, false, tdm_priv->id,
> > 0);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_tdm_mck_en_event(struct snd_soc_dapm_widget *w,
> > +				struct snd_kcontrol *kcontrol,
> > +				int event)
> > +{
> > +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int dai_id = get_tdm_id_by_name(w->name);
> > +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> > +
> > +	if (!tdm_priv) {
> > +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> 
> dev_err() - please fix all other instances
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x, dai_id %d\n",
> > +		__func__, w->name, event, dai_id);
> > +
> > +	switch (event) {
> > +	case SND_SOC_DAPM_PRE_PMU:
> > +		mt8186_mck_enable(afe, tdm_priv->mclk_id, tdm_priv-
> > >mclk_rate);
> > +		break;
> > +	case SND_SOC_DAPM_POST_PMD:
> > +		tdm_priv->mclk_rate = 0;
> > +		mt8186_mck_disable(afe, tdm_priv->mclk_id);
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> ...snip...
> 
> > +
> > +static int mt8186_tdm_hd_set(struct snd_kcontrol *kcontrol,
> > +			     struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int dai_id = get_tdm_id_by_name(kcontrol->id.name);
> > +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[dai_id];
> > +	struct soc_enum *e = (struct soc_enum *)kcontrol-
> > >private_value;
> > +	int hd_en;
> > +
> > +	if (ucontrol->value.enumerated.item[0] >= e->items)
> > +		return -EINVAL;
> > +
> > +	hd_en = ucontrol->value.integer.value[0];
> > +
> > +	dev_info(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
> > +		 __func__, kcontrol->id.name, hd_en);
> 
> dev_dbg()
> 
> > +
> > +	if (!tdm_priv) {
> > +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> > +		return -EINVAL;
> > +	}
> > +
> > +	tdm_priv->low_jitter_en = hd_en;
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct snd_kcontrol_new mtk_dai_tdm_controls[] = {
> > +	SOC_ENUM_EXT(MTK_AFE_TDM_KCONTROL_NAME, mt8186_tdm_enum[0],
> > +		     mt8186_tdm_hd_get, mt8186_tdm_hd_set),
> > +};
> > +
> > +static const struct snd_soc_dapm_route mtk_dai_tdm_routes[] = {
> > +	{"TDM IN", NULL, "aud_tdm_clk"},
> > +	{"TDM IN", NULL, "TDM_EN"},
> > +	{"TDM IN", NULL, TDM_HD_EN_W_NAME, mtk_afe_tdm_hd_connect},
> > +	{TDM_HD_EN_W_NAME, NULL, APLL1_W_NAME,
> > mtk_afe_tdm_apll_connect},
> > +	{TDM_HD_EN_W_NAME, NULL, APLL2_W_NAME,
> > mtk_afe_tdm_apll_connect},
> > +
> > +	{"TDM IN", NULL, TDM_MCLK_EN_W_NAME, mtk_afe_tdm_mclk_connect},
> > +	{TDM_MCLK_EN_W_NAME, NULL, APLL1_W_NAME,
> > mtk_afe_tdm_mclk_apll_connect},
> > +	{TDM_MCLK_EN_W_NAME, NULL, APLL2_W_NAME,
> > mtk_afe_tdm_mclk_apll_connect},
> > +
> > +	/* allow tdm on without codec on */
> > +	{"TDM IN", NULL, "TDM_In_Mux"},
> > +	{"TDM_In_Mux", "Dummy_Widget", "TDM_DUMMY_IN"},
> > +};
> > +
> > +/* dai ops */
> > +static int mtk_dai_tdm_cal_mclk(struct mtk_base_afe *afe,
> > +				struct mtk_afe_tdm_priv *tdm_priv,
> > +				int freq)
> > +{
> > +	int apll;
> > +	int apll_rate;
> > +
> > +	apll = mt8186_get_apll_by_rate(afe, freq);
> > +	apll_rate = mt8186_get_apll_rate(afe, apll);
> > +
> > +	if (!freq || freq > apll_rate) {
> > +		dev_info(afe->dev,
> > +			 "%s(), freq(%d Hz) invalid\n", __func__,
> > freq);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (apll_rate % freq != 0) {
> > +		dev_info(afe->dev,
> > +			 "%s(), APLL cannot generate %d Hz", __func__,
> > freq);
> > +		return -EINVAL;
> > +	}
> > +
> > +	tdm_priv->mclk_rate = freq;
> > +	tdm_priv->mclk_apll = apll;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream
> > *substream,
> > +				 struct snd_pcm_hw_params *params,
> > +				 struct snd_soc_dai *dai)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int tdm_id = dai->id;
> > +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
> > +	unsigned int tdm_mode = tdm_priv->tdm_mode;
> > +	unsigned int data_mode = tdm_priv->data_mode;
> > +	unsigned int rate = params_rate(params);
> > +	unsigned int channels = params_channels(params);
> > +	snd_pcm_format_t format = params_format(params);
> > +	unsigned int bit_width =
> > +		snd_pcm_format_physical_width(format);
> > +	unsigned int tdm_channels = (data_mode == TDM_DATA_ONE_PIN) ?
> > +		get_tdm_ch_per_sdata(tdm_mode, channels) : 2;
> > +	unsigned int lrck_width =
> > +		get_tdm_lrck_width(format, tdm_mode);
> > +	unsigned int tdm_con = 0;
> > +	bool slave_mode = tdm_priv->slave_mode;
> > +	bool lrck_inv = tdm_priv->lck_invert;
> > +	bool bck_inv = tdm_priv->bck_invert;
> > +	unsigned int ctrl_reg;
> > +	unsigned int ctrl_mask;
> > +	unsigned int tran_rate;
> > +	unsigned int tran_relatch_rate;
> > +
> > +	if (tdm_priv)
> > +		tdm_priv->rate = rate;
> > +	else
> > +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> > +
> > +	tran_rate = mt8186_rate_transform(afe->dev, rate, dai->id);
> > +	tran_relatch_rate = mt8186_tdm_relatch_rate_transform(afe->dev, 
> > rate);
> > +
> > +	/* calculate mclk_rate, if not set explicitly */
> > +	if (!tdm_priv->mclk_rate) {
> > +		tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple;
> > +		mtk_dai_tdm_cal_mclk(afe,
> > +				     tdm_priv,
> > +				     tdm_priv->mclk_rate);
> > +	}
> > +
> > +	/* ETDM_IN1_CON0 */
> > +	tdm_con |= slave_mode << ETDM_IN1_CON0_REG_SLAVE_MODE_SFT;
> > +	tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT;
> > +	tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_BIT_LENGTH_SFT;
> > +	tdm_con |= (bit_width - 1) <<
> > ETDM_IN1_CON0_REG_WORD_LENGTH_SFT;
> > +	tdm_con |= (tdm_channels - 1) << ETDM_IN1_CON0_REG_CH_NUM_SFT;
> > +	/* default disable sync mode */
> > +	tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT;
> 
> 0 << (anything) == 0
> 
> (number |= 0) == number
> 
> Is this a mistake, or are you really doing nothing here?
> 
No, this is just to emphasize the need to set this bit to 0.
It really do nothing here, just link a reminder.
Can I keep this sentence?
> 
> > +	/* relatch fix to h26m */
> > +	tdm_con |= 0 << ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT;
> > +
> > +	ctrl_reg = ETDM_IN1_CON0;
> > +	ctrl_mask = ETDM_IN_CON0_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> > +
> > +	/* ETDM_IN1_CON1 */
> > +	tdm_con = 0;
> > +	tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT;
> > +	tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT;
> > +	tdm_con |= (lrck_width - 1) <<
> > ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT;
> > +
> > +	ctrl_reg = ETDM_IN1_CON1;
> > +	ctrl_mask = ETDM_IN_CON1_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> 
> You don't need the ctrl_reg, nor ctrl_mask variables...
I was trying to avoid a line of more than 80 words, so I shortened the
number of words through variables.

> 
> regmap_update_bits(afe->regmap, ETDM_IN1_CON1,
> ETDM_IN_CON1_CTRL_MASK, tdm_con);
> 
> > +
> > +	/* ETDM_IN1_CON3 */
> > +	tdm_con = 0;
> > +	tdm_con = ETDM_IN_CON3_FS(tran_rate);
> > +
> > +	ctrl_reg = ETDM_IN1_CON3;
> > +	ctrl_mask = ETDM_IN_CON3_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> 
> same here
> 
> > +
> > +	/* ETDM_IN1_CON4 */
> > +	tdm_con = 0;
> > +	tdm_con = ETDM_IN_CON4_FS(tran_relatch_rate);
> > +	if (slave_mode) {
> > +		if (lrck_inv)
> > +			tdm_con |= ETDM_IN_CON4_CON0_SLAVE_LRCK_INV;
> > +		if (bck_inv)
> > +			tdm_con |= ETDM_IN_CON4_CON0_SLAVE_BCK_INV;
> > +	} else {
> > +		if (lrck_inv)
> > +			tdm_con |= ETDM_IN_CON4_CON0_MASTER_LRCK_INV;
> > +		if (bck_inv)
> > +			tdm_con |= ETDM_IN_CON4_CON0_MASTER_BCK_INV;
> > +	}
> > +
> > +	ctrl_reg = ETDM_IN1_CON4;
> > +	ctrl_mask = ETDM_IN_CON4_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> 
> and here
> 
> > +
> > +	/* ETDM_IN1_CON2 */
> > +	tdm_con = 0;
> > +	if (data_mode == TDM_DATA_MULTI_PIN) {
> > +		tdm_con |= ETDM_IN_CON2_MULTI_IP_2CH_MODE;
> > +		tdm_con |= ETDM_IN_CON2_MULTI_IP_CH(channels);
> > +	}
> > +
> > +	ctrl_reg = ETDM_IN1_CON2;
> > +	ctrl_mask = ETDM_IN_CON2_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> 
> and here
> 
> > +
> > +	/* ETDM_IN1_CON8 */
> > +	tdm_con = 0;
> > +	if (slave_mode) {
> > +		tdm_con |= 1 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT;
> > +		tdm_con |= 0 <<
> > ETDM_IN1_CON8_REG_AFIFO_CLOCK_DOMAIN_SEL_SFT;
> > +		tdm_con |= ETDM_IN_CON8_FS(tran_relatch_rate);
> > +	} else {
> > +		tdm_con |= 0 << ETDM_IN1_CON8_REG_ETDM_USE_AFIFO_SFT;
> > +	}
> > +
> > +	ctrl_reg = ETDM_IN1_CON8;
> > +	ctrl_mask = ETDM_IN_CON8_CTRL_MASK;
> > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
> 
> finally, here too.
> 
> > +
> > +	return 0;
> > +}
> > +
> 
> Thanks,
> ANgelo
AngeloGioacchino Del Regno March 3, 2022, 3:08 p.m. UTC | #14
Il 03/03/22 15:10, Jiaxin Yu ha scritto:
> On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
>> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
>>> This patch adds mt8186 tdm dai driver.
>>>
>>> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> ---
>>>    sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 713
>>> +++++++++++++++++++++
>>>    1 file changed, 713 insertions(+)
>>>    create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
>>>
>>> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
>>> b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
>>> new file mode 100644
>>> index 000000000000..28dd3661f0e0
>>> --- /dev/null
>>> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
>>> @@ -0,0 +1,713 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +//
>>> +// MediaTek ALSA SoC Audio DAI TDM Control
>>> +//
>>> +// Copyright (c) 2022 MediaTek Inc.
>>> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> +

..snip..

>>> +
>>> +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream
>>> *substream,
>>> +				 struct snd_pcm_hw_params *params,
>>> +				 struct snd_soc_dai *dai)
>>> +{
>>> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
>>> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
>>> +	int tdm_id = dai->id;
>>> +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv->dai_priv[tdm_id];
>>> +	unsigned int tdm_mode = tdm_priv->tdm_mode;
>>> +	unsigned int data_mode = tdm_priv->data_mode;
>>> +	unsigned int rate = params_rate(params);
>>> +	unsigned int channels = params_channels(params);
>>> +	snd_pcm_format_t format = params_format(params);
>>> +	unsigned int bit_width =
>>> +		snd_pcm_format_physical_width(format);
>>> +	unsigned int tdm_channels = (data_mode == TDM_DATA_ONE_PIN) ?
>>> +		get_tdm_ch_per_sdata(tdm_mode, channels) : 2;
>>> +	unsigned int lrck_width =
>>> +		get_tdm_lrck_width(format, tdm_mode);
>>> +	unsigned int tdm_con = 0;
>>> +	bool slave_mode = tdm_priv->slave_mode;
>>> +	bool lrck_inv = tdm_priv->lck_invert;
>>> +	bool bck_inv = tdm_priv->bck_invert;
>>> +	unsigned int ctrl_reg;
>>> +	unsigned int ctrl_mask;
>>> +	unsigned int tran_rate;
>>> +	unsigned int tran_relatch_rate;
>>> +
>>> +	if (tdm_priv)
>>> +		tdm_priv->rate = rate;
>>> +	else
>>> +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
>>> +
>>> +	tran_rate = mt8186_rate_transform(afe->dev, rate, dai->id);
>>> +	tran_relatch_rate = mt8186_tdm_relatch_rate_transform(afe->dev,
>>> rate);
>>> +
>>> +	/* calculate mclk_rate, if not set explicitly */
>>> +	if (!tdm_priv->mclk_rate) {
>>> +		tdm_priv->mclk_rate = rate * tdm_priv->mclk_multiple;
>>> +		mtk_dai_tdm_cal_mclk(afe,
>>> +				     tdm_priv,
>>> +				     tdm_priv->mclk_rate);
>>> +	}
>>> +
>>> +	/* ETDM_IN1_CON0 */
>>> +	tdm_con |= slave_mode << ETDM_IN1_CON0_REG_SLAVE_MODE_SFT;
>>> +	tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT;
>>> +	tdm_con |= (bit_width - 1) << ETDM_IN1_CON0_REG_BIT_LENGTH_SFT;
>>> +	tdm_con |= (bit_width - 1) <<
>>> ETDM_IN1_CON0_REG_WORD_LENGTH_SFT;
>>> +	tdm_con |= (tdm_channels - 1) << ETDM_IN1_CON0_REG_CH_NUM_SFT;
>>> +	/* default disable sync mode */
>>> +	tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT;
>>
>> 0 << (anything) == 0
>>
>> (number |= 0) == number
>>
>> Is this a mistake, or are you really doing nothing here?
>>
> No, this is just to emphasize the need to set this bit to 0.
> It really do nothing here, just link a reminder.
> Can I keep this sentence?

If, in your judgement, it is very important to have a reminder about that
bit having to be unset, then add a comment in the code saying so.
Don't simply comment out the statement as it is.

A good way would be something like
/* sync mode bit has to be unset because this that reason, otherwise X happens */

>>
>>> +	/* relatch fix to h26m */
>>> +	tdm_con |= 0 << ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT;
>>> +
>>> +	ctrl_reg = ETDM_IN1_CON0;
>>> +	ctrl_mask = ETDM_IN_CON0_CTRL_MASK;
>>> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
>>> +
>>> +	/* ETDM_IN1_CON1 */
>>> +	tdm_con = 0;
>>> +	tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT;
>>> +	tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT;
>>> +	tdm_con |= (lrck_width - 1) <<
>>> ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT;
>>> +
>>> +	ctrl_reg = ETDM_IN1_CON1;
>>> +	ctrl_mask = ETDM_IN_CON1_CTRL_MASK;
>>> +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask, tdm_con);
>>
>> You don't need the ctrl_reg, nor ctrl_mask variables...
> I was trying to avoid a line of more than 80 words, so I shortened the
> number of words through variables.
> 

Yes, I know, I did understand what you were trying to do...
...but it's fine to go past 80: in this case this would be 88 columns,
which is still ok to have!

And note, this is the case with all of similar calls present in this function,
that's why I said that you don't need these two variables! :)

Thank you,
Angelo
Jiaxin Yu (俞家鑫) March 3, 2022, 3:16 p.m. UTC | #15
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch add audio clock control with CCF interface.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-afe-clk.c | 719
> > +++++++++++++++++++++
> >   sound/soc/mediatek/mt8186/mt8186-afe-clk.h | 210 ++++++
> >   2 files changed, 929 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > new file mode 100644
> > index 000000000000..14f64b935619
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > @@ -0,0 +1,719 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// mt8186-afe-clk.c  --  Mediatek 8186 afe clock ctrl
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/clk.h>
> > +#include <linux/regmap.h>
> > +#include <linux/mfd/syscon.h>
> > +
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-audsys-clk.h"
> > +
> > +static DEFINE_MUTEX(mutex_request_dram);
> > +
> > +static const char *aud_clks[CLK_NUM] = {
> > +	[CLK_AFE] = "aud_afe_clk",
> > +	[CLK_DAC] = "aud_dac_clk",
> > +	[CLK_DAC_PREDIS] = "aud_dac_predis_clk",
> > +	[CLK_ADC] = "aud_adc_clk",
> > +	[CLK_TML] = "aud_tml_clk",
> > +	[CLK_APLL22M] = "aud_apll22m_clk",
> > +	[CLK_APLL24M] = "aud_apll24m_clk",
> > +	[CLK_APLL1_TUNER] = "aud_apll_tuner_clk",
> > +	[CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",
> > +	[CLK_TDM] = "aud_tdm_clk",
> > +	[CLK_NLE] = "aud_nle_clk",
> > +	[CLK_DAC_HIRES] = "aud_dac_hires_clk",
> > +	[CLK_ADC_HIRES] = "aud_adc_hires_clk",
> > +	[CLK_I2S1_BCLK] = "aud_i2s1_bclk",
> > +	[CLK_I2S2_BCLK] = "aud_i2s2_bclk",
> > +	[CLK_I2S3_BCLK] = "aud_i2s3_bclk",
> > +	[CLK_I2S4_BCLK] = "aud_i2s4_bclk",
> > +	[CLK_CONNSYS_I2S_ASRC] = "aud_connsys_i2s_asrc",
> > +	[CLK_GENERAL1_ASRC] = "aud_general1_asrc",
> > +	[CLK_GENERAL2_ASRC] = "aud_general2_asrc",
> > +	[CLK_ADC_HIRES_TML] = "aud_adc_hires_tml",
> > +	[CLK_ADDA6_ADC] = "aud_adda6_adc",
> > +	[CLK_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires",
> > +	[CLK_3RD_DAC] = "aud_3rd_dac",
> > +	[CLK_3RD_DAC_PREDIS] = "aud_3rd_dac_predis",
> > +	[CLK_3RD_DAC_TML] = "aud_3rd_dac_tml",
> > +	[CLK_3RD_DAC_HIRES] = "aud_3rd_dac_hires",
> > +	[CLK_ETDM_IN1_BCLK] = "aud_etdm_in1_bclk",
> > +	[CLK_ETDM_OUT1_BCLK] = "aud_etdm_out1_bclk",
> > +	[CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",
> > +	[CLK_INFRA_AUDIO_26M] = "mtkaif_26m_clk",
> > +	[CLK_MUX_AUDIO] = "top_mux_audio",
> > +	[CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int",
> > +	[CLK_TOP_MAINPLL_D2_D4] = "top_mainpll_d2_d4",
> > +	[CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",
> > +	[CLK_TOP_APLL1_CK] = "top_apll1_ck",
> > +	[CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",
> > +	[CLK_TOP_APLL2_CK] = "top_apll2_ck",
> > +	[CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",
> > +	[CLK_TOP_APLL1_D8] = "top_apll1_d8",
> > +	[CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",
> > +	[CLK_TOP_APLL2_D8] = "top_apll2_d8",
> > +	[CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h",
> > +	[CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",
> > +	[CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",
> > +	[CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",
> > +	[CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",
> > +	[CLK_TOP_TDM_M_SEL] = "top_tdm_m_sel",
> > +	[CLK_TOP_APLL12_DIV0] = "top_apll12_div0",
> > +	[CLK_TOP_APLL12_DIV1] = "top_apll12_div1",
> > +	[CLK_TOP_APLL12_DIV2] = "top_apll12_div2",
> > +	[CLK_TOP_APLL12_DIV4] = "top_apll12_div4",
> > +	[CLK_TOP_APLL12_DIV_TDM] = "top_apll12_div_tdm",
> > +	[CLK_CLK26M] = "top_clk26m_clk",
> > +};
> > +
> > +int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe,
> > +				    int clk_id)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],
> > +			     afe_priv->clk[clk_id]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS],
> > +			 aud_clks[clk_id], ret);
> 
> 		dev_err(......)
> 		return ret;
> 
> > +	}
> > +
> 
> 	return 0;
> 
> > +	return ret;
> > +}
> > +
> > +static int apll1_mux_setting(struct mtk_base_afe *afe, bool
> > enable)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	if (enable) {
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_1]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> > +				     afe_priv->clk[CLK_TOP_APLL1_CK]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > +				 aud_clks[CLK_TOP_APLL1_CK], ret);
> 
> dev_err()
> 
> > +			goto EXIT;
> > +		}
> > +
> > +		/* 180.6336 / 8 = 22.5792MHz */
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1],
> > +				     afe_priv->clk[CLK_TOP_APLL1_D8]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1],
> > +				 aud_clks[CLK_TOP_APLL1_D8], ret);
> > +			goto EXIT;
> > +		}
> > +	} else {
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1]);
> > +
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_1]);
> > +	}
> > +EXIT:
> > +	return 0;
> 
> You're returning 0 even in error cases, this is wrong.
Thanka for your careful review. I will fix this issue in next version.

> 
> > +}
> > +
> > +static int apll2_mux_setting(struct mtk_base_afe *afe, bool
> > enable)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	if (enable) {
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_2]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> > +				     afe_priv->clk[CLK_TOP_APLL2_CK]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > +				 aud_clks[CLK_TOP_APLL2_CK], ret);
> > +			goto EXIT;
> > +		}
> > +
> > +		/* 196.608 / 8 = 24.576MHz */
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2],
> > +				     afe_priv->clk[CLK_TOP_APLL2_D8]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2],
> > +				 aud_clks[CLK_TOP_APLL2_D8], ret);
> > +			goto EXIT;
> > +		}
> > +	} else {
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2]);
> > +
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_2]);
> > +	}
> > +
> > +EXIT:
> > +	return 0;
> > +}
> > +
> > +int mt8186_afe_enable_cgs(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +	int i;
> > +
> > +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) {
> > +		ret = clk_prepare_enable(afe_priv->clk[i]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[i], ret);
> 
> dev_err()
> 
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_afe_disable_cgs(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int i;
> > +
> > +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++)
> > +		clk_disable_unprepare(afe_priv->clk[i]);
> > +}
> > +
> > +int mt8186_afe_enable_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);
> 
> dev_err()
> 
> > +		goto CLK_INFRA_SYS_AUDIO_ERR;
> 
> also, please use lower-case labels (here and everywhere else).
> 
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_INFRA_AUDIO_26M], ret);
> > +		goto CLK_INFRA_AUDIO_26M_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIO], ret);
> > +		goto CLK_MUX_AUDIO_ERR;
> > +	}
> > +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],
> > +			     afe_priv->clk[CLK_CLK26M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIO],
> > +			 aud_clks[CLK_CLK26M], ret);
> > +		goto CLK_MUX_AUDIO_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe,
> > +					      CLK_TOP_MAINPLL_D2_D4);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H],
> > +			     afe_priv->clk[CLK_TOP_APLL2_CK]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_TOP_MUX_AUDIO_H],
> > +			 aud_clks[CLK_TOP_APLL2_CK], ret);
> > +		goto CLK_MUX_AUDIO_H_PARENT_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_AFE], ret);
> > +		goto CLK_AFE_ERR;
> > +	}
> > +
> > +	return 0;
> > +
> > +CLK_AFE_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> > +CLK_MUX_AUDIO_H_PARENT_ERR:
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +CLK_MUX_AUDIO_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> > +CLK_INFRA_SYS_AUDIO_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +CLK_INFRA_AUDIO_26M_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_afe_disable_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +}
> > +
> > +int mt8186_afe_suspend_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* set audio int bus to 26M */
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> 
> dev_err() - here and for the other similar instances.
> 
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +
> > +	return 0;
> > +
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	return ret;
> > +}
> > +
> > +int mt8186_afe_resume_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* set audio int bus to normal working clock */
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe,
> > +					      CLK_TOP_MAINPLL_D2_D4);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +
> > +	return 0;
> > +
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	return ret;
> > +}
> > +
> > +int mt8186_apll1_enable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* setting for APLL */
> > +	apll1_mux_setting(afe, true);
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL22M], ret);
> > +		goto ERR_CLK_APLL22M;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL1_TUNER], ret);
> > +		goto ERR_CLK_APLL1_TUNER;
> > +	}
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
> > +			   0x0000FFF7, 0x00000832);
> 
> no leading zeroes - and without them, it fits in one line.
> 
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_22M_ON_MASK_SFT,
> > +			   0x1 << AFE_22M_ON_SFT);
> 
> BIT() macro please
> 
> > +
> > +	return 0;
> > +
> > +ERR_CLK_APLL1_TUNER:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> > +ERR_CLK_APLL22M:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_apll1_disable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_22M_ON_MASK_SFT,
> > +			   0x0 << AFE_22M_ON_SFT);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0);
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> > +
> > +	apll1_mux_setting(afe, false);
> > +}
> > +
> > +int mt8186_apll2_enable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* setting for APLL */
> > +	apll2_mux_setting(afe, true);
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL24M], ret);
> > +		goto ERR_CLK_APLL24M;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL2_TUNER], ret);
> > +		goto ERR_CLK_APLL2_TUNER;
> > +	}
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
> > +			   0x0000FFF7, 0x00000634);
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_24M_ON_MASK_SFT,
> > +			   0x1 << AFE_24M_ON_SFT);
> > +
> > +	return 0;
> > +
> > +ERR_CLK_APLL2_TUNER:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> > +ERR_CLK_APLL24M:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_apll2_disable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_24M_ON_MASK_SFT,
> > +			   0x0 << AFE_24M_ON_SFT);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0);
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> > +
> > +	apll2_mux_setting(afe, false);
> > +}
> > +
> > +int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll)
> > +{
> > +	return (apll == MT8186_APLL1) ? 180633600 : 196608000;
> > +}
> > +
> > +int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
> > +{
> > +	return ((rate % 8000) == 0) ? MT8186_APLL2 : MT8186_APLL1;
> > +}
> > +
> > +int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char
> > *name)
> > +{
> > +	if (strcmp(name, APLL1_W_NAME) == 0)
> > +		return MT8186_APLL1;
> > +	else
> > +		return MT8186_APLL2;
> > +}
> > +
> > +/* mck */
> > +struct mt8186_mck_div {
> > +	int m_sel_id;
> > +	int div_clk_id;
> > +	/* below will be deprecated */
> > +	int div_pdn_reg;
> > +	int div_pdn_mask_sft;
> > +	int div_reg;
> > +	int div_mask_sft;
> > +	int div_mask;
> > +	int div_sft;
> > +	int div_msb_reg;
> > +	int div_msb_mask_sft;
> > +	int div_msb_mask;
> > +	int div_msb_sft;
> > +	int div_apll_sel_reg;
> > +	int div_apll_sel_mask_sft;
> > +	int div_apll_sel_sft;
> > +	int div_inv_reg;
> > +	int div_inv_mask_sft;
> 
> 
> 
> *_reg fits in u16.
> *_mask_sft, *_sel_sft can be u32.
> 
> This would be nice to avoid wasting memory for variables that are
> larger than
> needed; besides, you're also using a signed type for a number that
> may not
> ever be less than zero.
> 
Yes, your suggestion is very correct. But I will remove some member fo
this strcut because they are not needed in audio driver.

> 
> > +};
> > +
> > +static const struct mt8186_mck_div mck_div[MT8186_MCK_NUM] = {
> > +	[MT8186_I2S0_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S0_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV0,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV0_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV0_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV0_MASK,
> > +		.div_sft = APLL12_CK_DIV0_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S0_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S0_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S1_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S1_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV1,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV1_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV1_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV1_MASK,
> > +		.div_sft = APLL12_CK_DIV1_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S1_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S1_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S2_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S2_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV2,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV2_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV2_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV2_MASK,
> > +		.div_sft = APLL12_CK_DIV2_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S2_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S2_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S4_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S4_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV4,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV4_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV4_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV4_MASK,
> > +		.div_sft = APLL12_CK_DIV4_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S4_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S4_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_TDM_MCK] = {
> > +		.m_sel_id = CLK_TOP_TDM_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV_TDM,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV_TDM_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_3,
> > +		.div_mask_sft = APLL12_CK_DIV_TDM_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV_TDM_MASK,
> > +		.div_sft = APLL12_CK_DIV_TDM_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_TDM_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_TDM_MCK_SEL_SFT,
> > +	},
> > +};
> > +
> > +int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int
> > rate)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int apll = mt8186_get_apll_by_rate(afe, rate);
> > +	int apll_clk_id = apll == MT8186_APLL1 ?
> > +			  CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;
> > +	int m_sel_id = mck_div[mck_id].m_sel_id;
> > +	int div_clk_id = mck_div[mck_id].div_clk_id;
> > +	int ret;
> > +
> > +	/* select apll */
> > +	if (m_sel_id >= 0) {
> > +		ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[m_sel_id], ret);
> 
> dev_err()
> 
> > +			return ret;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[m_sel_id],
> > +				     afe_priv->clk[apll_clk_id]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[m_sel_id],
> > +				aud_clks[apll_clk_id], ret);
> 
> again
> 
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	/* enable div, set rate */
> > +	ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s(), clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[div_clk_id], ret);
> 
> again
> 
> > +		return ret;
> > +	}
> > +	ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s(), clk_set_rate %s, rate %d,
> > fail %d\n",
> > +			 __func__, aud_clks[div_clk_id],
> > +			 rate, ret);
> 
> again - and this fits in two lines.
> 
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int m_sel_id = mck_div[mck_id].m_sel_id;
> > +	int div_clk_id = mck_div[mck_id].div_clk_id;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[div_clk_id]);
> > +	if (m_sel_id >= 0)
> > +		clk_disable_unprepare(afe_priv->clk[m_sel_id]);
> > +}
> > +
> > +int mt8186_init_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct device_node *of_node = afe->dev->of_node;
> > +	int i = 0;
> > +
> > +	 mt8186_audsys_clk_register(afe);
> 
> Fix indentation please
> 
> > +
> > +	afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM,
> > sizeof(*afe_priv->clk),
> > +				     GFP_KERNEL);
> > +	if (!afe_priv->clk)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < CLK_NUM; i++) {
> > +		afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
> > +		if (IS_ERR(afe_priv->clk[i])) {
> > +			dev_info(afe->dev, "%s devm_clk_get %s fail,
> > ret %ld\n",
> > +				 __func__,
> > +				 aud_clks[i], PTR_ERR(afe_priv-
> > >clk[i]));
> > +			afe_priv->clk[i] = NULL;
> > +		}
> > +	}
> > +
> > +	afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node,
> > +							       "mediate
> > k,apmixedsys");
> > +	if (IS_ERR(afe_priv->apmixedsys)) {
> > +		dev_err(afe->dev, "%s() Cannot find apmixedsys
> > controller: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->apmixedsys));
> > +		return PTR_ERR(afe_priv->apmixedsys);
> > +	}
> > +
> > +	afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node,
> > +							     "mediatek,
> > topckgen");
> > +	if (IS_ERR(afe_priv->topckgen)) {
> > +		dev_err(afe->dev, "%s() Cannot find topckgen
> > controller: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->topckgen));
> > +		return PTR_ERR(afe_priv->topckgen);
> > +	}
> > +
> > +	afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node,
> > +							     "mediatek,
> > infracfg");
> > +	if (IS_ERR(afe_priv->infracfg)) {
> > +		dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->infracfg));
> > +		return PTR_ERR(afe_priv->infracfg);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_deinit_clock(struct mtk_base_afe *afe)
> > +{
> > +	mt8186_audsys_clk_unregister(afe);
> > +}
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > new file mode 100644
> > index 000000000000..3ce7a9a24d4a
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > @@ -0,0 +1,210 @@
> > +/* SPDX-License-Identifier: GPL-2.0
> > + *
> > + * mt8186-afe-clk.h  --  Mediatek 8186 afe clock ctrl definition
> > + *
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > + */
> > +
> > +#ifndef _MT8186_AFE_CLOCK_CTRL_H_
> > +#define _MT8186_AFE_CLOCK_CTRL_H_
> > +
> > +#define PERI_BUS_DCM_CTRL 0x0074
> > +#define MODULE_SW_CG_1_STA 0x0094
> > +#define MODULE_SW_CG_2_STA 0x00ac
> > +#define CLK_CFG_7 0x0080
> > +#define CLK_CFG_8 0x0090
> > +#define CLK_CFG_11 0x00c0
> > +#define CLK_CFG_12 0x00d0
> > +#define CLK_CFG_13 0x00e0
> > +#define CLK_CFG_15 0x0100
> > +#define AP_PLL_CON3 0x0014
> > +#define APLL1_CON4 0x0328
> > +#define APLL1_TUNER_CON0 0x0040
> > +#define APLL2_CON4 0x033c
> > +#define APLL2_TUNER_CON0 0x0044
> > +
> > +#define AP_PLL_CON5 0x0014
> > +#define APLL1_CON0 0x02c0
> > +#define APLL1_CON1 0x02c4
> > +#define APLL1_CON2 0x02c8
> > +#define APLL1_CON3 0x02cc
> > +#define APLL1_PWR_CON0 0x02d0
> > +
> > +#define APLL2_CON0 0x02d4
> > +#define APLL2_CON1 0x02d8
> > +#define APLL2_CON2 0x02dc
> > +#define APLL2_CON3 0x02e0
> > +#define APLL2_PWR_CON0 0x02e4
> > +
> > +#define APMIXEDSYS_MAX_LENGTH APLL2_PWR_CON0
> > +
> > +#define CLK_CFG_6 0x0080
> > +#define CLK_AUDDIV_0 0x0320
> > +#define CLK_AUDDIV_1 0x0324
> > +#define CLK_AUDDIV_2 0x0328
> > +#define CKSYS_AUD_TOP_CFG 0x032c
> > +#define CKSYS_AUD_TOP_MON 0x0330
> > +#define CLK_AUDDIV_3 0x0334
> > +
> > +#define CLK_MAX_LENGTH CLK_AUDDIV_3
> > +
> > +/* CLK_CFG_6 */
> > +#define CLK_AUD_INTBUS_SEL_SFT              16
> > +#define CLK_AUD_INTBUS_SEL_MASK             0x3
> > +#define CLK_AUD_INTBUS_SEL_MASK_SFT         (0x3 << 16)
> 
> #define CLK_AUD_INTBUS_SEL_MASK_SFT		GENMASK(23, 22)
> 
I will remove these define because they are not used in audio driver.

> > +
> > +/* CLK_AUDDIV_0 */
> > +#define APLL12_DIV0_PDN_SFT                0
> > +#define APLL12_DIV0_PDN_MASK               0x1
> > +#define APLL12_DIV0_PDN_MASK_SFT           (0x1 << 0)
> 
> BIT() macro please
same

> 
> #define APLL12_DIV0_PDN_MASK_SFT		BIT(0)
> 
> also, using tabulations instead of spaces is nicer.
> 
> > +#define APLL12_DIV1_PDN_SFT                1
> > +#define APLL12_DIV1_PDN_MASK               0x1
> > +#define APLL12_DIV1_PDN_MASK_SFT           (0x1 << 1)
> 
> Of course, BIT() macro again, here and everywhere else applicable.
Yes, you are right.

> 
> > +#define APLL12_DIV2_PDN_SFT                2
> > +#define APLL12_DIV2_PDN_MASK               0x1
> > +#define APLL12_DIV2_PDN_MASK_SFT           (0x1 << 2)
> > +#define APLL12_DIV4_PDN_SFT                3
> > +#define APLL12_DIV4_PDN_MASK               0x1
> > +#define APLL12_DIV4_PDN_MASK_SFT           (0x1 << 3)
> > +#define APLL12_DIV_TDM_PDN_SFT             4
> > +#define APLL12_DIV_TDM_PDN_MASK            0x1
> > +#define APLL12_DIV_TDM_PDN_MASK_SFT        (0x1 << 4)
> > +#define APLL_I2S0_MCK_SEL_SFT              16
> > +#define APLL_I2S0_MCK_SEL_MASK             0x1
> > +#define APLL_I2S0_MCK_SEL_MASK_SFT         (0x1 << 16)
> > +#define APLL_I2S1_MCK_SEL_SFT              17
> > +#define APLL_I2S1_MCK_SEL_MASK             0x1
> > +#define APLL_I2S1_MCK_SEL_MASK_SFT         (0x1 << 17)
> > +#define APLL_I2S2_MCK_SEL_SFT              18
> > +#define APLL_I2S2_MCK_SEL_MASK             0x1
> > +#define APLL_I2S2_MCK_SEL_MASK_SFT         (0x1 << 17)
> > +#define APLL_I2S4_MCK_SEL_SFT              19
> > +#define APLL_I2S4_MCK_SEL_MASK             0x1
> > +#define APLL_I2S4_MCK_SEL_MASK_SFT         (0x1 << 19)
> > +#define APLL_TDM_MCK_SEL_SFT               20
> > +#define APLL_TDM_MCK_SEL_MASK              0x1
> > +#define APLL_TDM_MCK_SEL_MASK_SFT          (0x1 << 20)
> > +
> > +/* CLK_AUDDIV_2 */
> > +#define APLL12_CK_DIV0_SFT                 0
> > +#define APLL12_CK_DIV0_MASK                0xff
> > +#define APLL12_CK_DIV0_MASK_SFT            (0xff << 0)
> 
> GENMASK(7, 0)
> 
> > +#define APLL12_CK_DIV1_SFT                 8
> > +#define APLL12_CK_DIV1_MASK                0xff
> > +#define APLL12_CK_DIV1_MASK_SFT            (0xff << 8)
> 
> GENMASK(15, 8)
> 
> > +#define APLL12_CK_DIV2_SFT                 16
> > +#define APLL12_CK_DIV2_MASK                0xff
> > +#define APLL12_CK_DIV2_MASK_SFT            (0xff << 16)
> 
> Fix all the others too :))
> 
> > +#define APLL12_CK_DIV4_SFT                 24
> > +#define APLL12_CK_DIV4_MASK                0xff
> > +#define APLL12_CK_DIV4_MASK_SFT            (0xff << 24)
> > +
> > +/* CLK_AUDDIV_3 */
> > +#define APLL12_CK_DIV_TDM_SFT              0
> > +#define APLL12_CK_DIV_TDM_MASK             0xff
> > +#define APLL12_CK_DIV_TDM_MASK_SFT         (0xff << 0)
> > +
> > +/* AUD_TOP_CFG */
> > +#define AUD_TOP_CFG_SFT                    0
> > +#define AUD_TOP_CFG_MASK                   0xffffffff
> > +#define AUD_TOP_CFG_MASK_SFT               (0xffffffff << 0)
> 
> This is GENMASK(31, 0) for both MASK and MASK_SFT
> 
> > +
> > +/* AUD_TOP_MON */
> > +#define AUD_TOP_MON_SFT                    0
> > +#define AUD_TOP_MON_MASK                   0xffffffff
> > +#define AUD_TOP_MON_MASK_SFT               (0xffffffff << 0)
> 
> same here
> 
> 
> 
> Regards,
> Angelo
Jiaxin Yu (俞家鑫) March 3, 2022, 3:17 p.m. UTC | #16
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch add audio clock control with CCF interface.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-afe-clk.c | 719
> > +++++++++++++++++++++
> >   sound/soc/mediatek/mt8186/mt8186-afe-clk.h | 210 ++++++
> >   2 files changed, 929 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > new file mode 100644
> > index 000000000000..14f64b935619
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.c
> > @@ -0,0 +1,719 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// mt8186-afe-clk.c  --  Mediatek 8186 afe clock ctrl
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/clk.h>
> > +#include <linux/regmap.h>
> > +#include <linux/mfd/syscon.h>
> > +
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-audsys-clk.h"
> > +
> > +static DEFINE_MUTEX(mutex_request_dram);
> > +
> > +static const char *aud_clks[CLK_NUM] = {
> > +	[CLK_AFE] = "aud_afe_clk",
> > +	[CLK_DAC] = "aud_dac_clk",
> > +	[CLK_DAC_PREDIS] = "aud_dac_predis_clk",
> > +	[CLK_ADC] = "aud_adc_clk",
> > +	[CLK_TML] = "aud_tml_clk",
> > +	[CLK_APLL22M] = "aud_apll22m_clk",
> > +	[CLK_APLL24M] = "aud_apll24m_clk",
> > +	[CLK_APLL1_TUNER] = "aud_apll_tuner_clk",
> > +	[CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",
> > +	[CLK_TDM] = "aud_tdm_clk",
> > +	[CLK_NLE] = "aud_nle_clk",
> > +	[CLK_DAC_HIRES] = "aud_dac_hires_clk",
> > +	[CLK_ADC_HIRES] = "aud_adc_hires_clk",
> > +	[CLK_I2S1_BCLK] = "aud_i2s1_bclk",
> > +	[CLK_I2S2_BCLK] = "aud_i2s2_bclk",
> > +	[CLK_I2S3_BCLK] = "aud_i2s3_bclk",
> > +	[CLK_I2S4_BCLK] = "aud_i2s4_bclk",
> > +	[CLK_CONNSYS_I2S_ASRC] = "aud_connsys_i2s_asrc",
> > +	[CLK_GENERAL1_ASRC] = "aud_general1_asrc",
> > +	[CLK_GENERAL2_ASRC] = "aud_general2_asrc",
> > +	[CLK_ADC_HIRES_TML] = "aud_adc_hires_tml",
> > +	[CLK_ADDA6_ADC] = "aud_adda6_adc",
> > +	[CLK_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires",
> > +	[CLK_3RD_DAC] = "aud_3rd_dac",
> > +	[CLK_3RD_DAC_PREDIS] = "aud_3rd_dac_predis",
> > +	[CLK_3RD_DAC_TML] = "aud_3rd_dac_tml",
> > +	[CLK_3RD_DAC_HIRES] = "aud_3rd_dac_hires",
> > +	[CLK_ETDM_IN1_BCLK] = "aud_etdm_in1_bclk",
> > +	[CLK_ETDM_OUT1_BCLK] = "aud_etdm_out1_bclk",
> > +	[CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",
> > +	[CLK_INFRA_AUDIO_26M] = "mtkaif_26m_clk",
> > +	[CLK_MUX_AUDIO] = "top_mux_audio",
> > +	[CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int",
> > +	[CLK_TOP_MAINPLL_D2_D4] = "top_mainpll_d2_d4",
> > +	[CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",
> > +	[CLK_TOP_APLL1_CK] = "top_apll1_ck",
> > +	[CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",
> > +	[CLK_TOP_APLL2_CK] = "top_apll2_ck",
> > +	[CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",
> > +	[CLK_TOP_APLL1_D8] = "top_apll1_d8",
> > +	[CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",
> > +	[CLK_TOP_APLL2_D8] = "top_apll2_d8",
> > +	[CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h",
> > +	[CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",
> > +	[CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",
> > +	[CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",
> > +	[CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",
> > +	[CLK_TOP_TDM_M_SEL] = "top_tdm_m_sel",
> > +	[CLK_TOP_APLL12_DIV0] = "top_apll12_div0",
> > +	[CLK_TOP_APLL12_DIV1] = "top_apll12_div1",
> > +	[CLK_TOP_APLL12_DIV2] = "top_apll12_div2",
> > +	[CLK_TOP_APLL12_DIV4] = "top_apll12_div4",
> > +	[CLK_TOP_APLL12_DIV_TDM] = "top_apll12_div_tdm",
> > +	[CLK_CLK26M] = "top_clk26m_clk",
> > +};
> > +
> > +int mt8186_set_audio_int_bus_parent(struct mtk_base_afe *afe,
> > +				    int clk_id)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],
> > +			     afe_priv->clk[clk_id]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS],
> > +			 aud_clks[clk_id], ret);
> 
> 		dev_err(......)
> 		return ret;
> 
> > +	}
> > +
> 
> 	return 0;
> 
> > +	return ret;
> > +}
> > +
> > +static int apll1_mux_setting(struct mtk_base_afe *afe, bool
> > enable)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	if (enable) {
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_1]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> > +				     afe_priv->clk[CLK_TOP_APLL1_CK]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > +				 aud_clks[CLK_TOP_APLL1_CK], ret);
> 
> dev_err()
> 
> > +			goto EXIT;
> > +		}
> > +
> > +		/* 180.6336 / 8 = 22.5792MHz */
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1],
> > +				     afe_priv->clk[CLK_TOP_APLL1_D8]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1],
> > +				 aud_clks[CLK_TOP_APLL1_D8], ret);
> > +			goto EXIT;
> > +		}
> > +	} else {
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG1],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG1]);
> > +
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_1],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_1]);
> > +	}
> > +EXIT:
> > +	return 0;
> 
> You're returning 0 even in error cases, this is wrong.
> 
> > +}
> > +
> > +static int apll2_mux_setting(struct mtk_base_afe *afe, bool
> > enable)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	if (enable) {
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_2]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> > +				     afe_priv->clk[CLK_TOP_APLL2_CK]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > +				 aud_clks[CLK_TOP_APLL2_CK], ret);
> > +			goto EXIT;
> > +		}
> > +
> > +		/* 196.608 / 8 = 24.576MHz */
> > +		ret = clk_prepare_enable(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);
> > +			goto EXIT;
> > +		}
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2],
> > +				     afe_priv->clk[CLK_TOP_APLL2_D8]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2],
> > +				 aud_clks[CLK_TOP_APLL2_D8], ret);
> > +			goto EXIT;
> > +		}
> > +	} else {
> > +		ret = clk_set_parent(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__,
> > aud_clks[CLK_TOP_MUX_AUD_ENG2],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_ENG2]);
> > +
> > +		ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
> > +				     afe_priv->clk[CLK_CLK26M]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[CLK_TOP_MUX_AUD_2],
> > +				 aud_clks[CLK_CLK26M], ret);
> > +			goto EXIT;
> > +		}
> > +		clk_disable_unprepare(afe_priv-
> > >clk[CLK_TOP_MUX_AUD_2]);
> > +	}
> > +
> > +EXIT:
> > +	return 0;
> > +}
> > +
> > +int mt8186_afe_enable_cgs(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +	int i;
> > +
> > +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++) {
> > +		ret = clk_prepare_enable(afe_priv->clk[i]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[i], ret);
> 
> dev_err()
> 
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_afe_disable_cgs(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int i;
> > +
> > +	for (i = CLK_I2S1_BCLK; i <= CLK_ETDM_OUT1_BCLK; i++)
> > +		clk_disable_unprepare(afe_priv->clk[i]);
> > +}
> > +
> > +int mt8186_afe_enable_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret = 0;
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);
> 
> dev_err()
> 
> > +		goto CLK_INFRA_SYS_AUDIO_ERR;
> 
> also, please use lower-case labels (here and everywhere else).
> 
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_INFRA_AUDIO_26M], ret);
> > +		goto CLK_INFRA_AUDIO_26M_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIO], ret);
> > +		goto CLK_MUX_AUDIO_ERR;
> > +	}
> > +	ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],
> > +			     afe_priv->clk[CLK_CLK26M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIO],
> > +			 aud_clks[CLK_CLK26M], ret);
> > +		goto CLK_MUX_AUDIO_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe,
> > +					      CLK_TOP_MAINPLL_D2_D4);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H],
> > +			     afe_priv->clk[CLK_TOP_APLL2_CK]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
> > +			 __func__, aud_clks[CLK_TOP_MUX_AUDIO_H],
> > +			 aud_clks[CLK_TOP_APLL2_CK], ret);
> > +		goto CLK_MUX_AUDIO_H_PARENT_ERR;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_AFE], ret);
> > +		goto CLK_AFE_ERR;
> > +	}
> > +
> > +	return 0;
> > +
> > +CLK_AFE_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> > +CLK_MUX_AUDIO_H_PARENT_ERR:
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +CLK_MUX_AUDIO_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> > +CLK_INFRA_SYS_AUDIO_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +CLK_INFRA_AUDIO_26M_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_afe_disable_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
> > +}
> > +
> > +int mt8186_afe_suspend_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* set audio int bus to 26M */
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> 
> dev_err() - here and for the other similar instances.
> 
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +
> > +	return 0;
> > +
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_TOP_MAINPLL_D2_D4);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	return ret;
> > +}
> > +
> > +int mt8186_afe_resume_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* set audio int bus to normal working clock */
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
> > +		goto CLK_MUX_AUDIO_INTBUS_ERR;
> > +	}
> > +	ret = mt8186_set_audio_int_bus_parent(afe,
> > +					      CLK_TOP_MAINPLL_D2_D4);
> > +	if (ret)
> > +		goto CLK_MUX_AUDIO_INTBUS_PARENT_ERR;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +
> > +	return 0;
> > +
> > +CLK_MUX_AUDIO_INTBUS_PARENT_ERR:
> > +	mt8186_set_audio_int_bus_parent(afe, CLK_CLK26M);
> > +CLK_MUX_AUDIO_INTBUS_ERR:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
> > +	return ret;
> > +}
> > +
> > +int mt8186_apll1_enable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* setting for APLL */
> > +	apll1_mux_setting(afe, true);
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL22M], ret);
> > +		goto ERR_CLK_APLL22M;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL1_TUNER], ret);
> > +		goto ERR_CLK_APLL1_TUNER;
> > +	}
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
> > +			   0x0000FFF7, 0x00000832);
> 
> no leading zeroes - and without them, it fits in one line.
> 
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_22M_ON_MASK_SFT,
> > +			   0x1 << AFE_22M_ON_SFT);
> 
> BIT() macro please
> 
> > +
> > +	return 0;
> > +
> > +ERR_CLK_APLL1_TUNER:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> > +ERR_CLK_APLL22M:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_apll1_disable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_22M_ON_MASK_SFT,
> > +			   0x0 << AFE_22M_ON_SFT);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0);
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
> > +
> > +	apll1_mux_setting(afe, false);
> > +}
> > +
> > +int mt8186_apll2_enable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	/* setting for APLL */
> > +	apll2_mux_setting(afe, true);
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL24M], ret);
> > +		goto ERR_CLK_APLL24M;
> > +	}
> > +
> > +	ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[CLK_APLL2_TUNER], ret);
> > +		goto ERR_CLK_APLL2_TUNER;
> > +	}
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
> > +			   0x0000FFF7, 0x00000634);
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_24M_ON_MASK_SFT,
> > +			   0x1 << AFE_24M_ON_SFT);
> > +
> > +	return 0;
> > +
> > +ERR_CLK_APLL2_TUNER:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> > +ERR_CLK_APLL24M:
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> > +
> > +	return ret;
> > +}
> > +
> > +void mt8186_apll2_disable(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
> > +			   AFE_24M_ON_MASK_SFT,
> > +			   0x0 << AFE_24M_ON_SFT);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0);
> > +
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
> > +	clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
> > +
> > +	apll2_mux_setting(afe, false);
> > +}
> > +
> > +int mt8186_get_apll_rate(struct mtk_base_afe *afe, int apll)
> > +{
> > +	return (apll == MT8186_APLL1) ? 180633600 : 196608000;
> > +}
> > +
> > +int mt8186_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
> > +{
> > +	return ((rate % 8000) == 0) ? MT8186_APLL2 : MT8186_APLL1;
> > +}
> > +
> > +int mt8186_get_apll_by_name(struct mtk_base_afe *afe, const char
> > *name)
> > +{
> > +	if (strcmp(name, APLL1_W_NAME) == 0)
> > +		return MT8186_APLL1;
> > +	else
> > +		return MT8186_APLL2;
> > +}
> > +
> > +/* mck */
> > +struct mt8186_mck_div {
> > +	int m_sel_id;
> > +	int div_clk_id;
> > +	/* below will be deprecated */
> > +	int div_pdn_reg;
> > +	int div_pdn_mask_sft;
> > +	int div_reg;
> > +	int div_mask_sft;
> > +	int div_mask;
> > +	int div_sft;
> > +	int div_msb_reg;
> > +	int div_msb_mask_sft;
> > +	int div_msb_mask;
> > +	int div_msb_sft;
> > +	int div_apll_sel_reg;
> > +	int div_apll_sel_mask_sft;
> > +	int div_apll_sel_sft;
> > +	int div_inv_reg;
> > +	int div_inv_mask_sft;
> 
> 
> 
> *_reg fits in u16.
> *_mask_sft, *_sel_sft can be u32.
> 
> This would be nice to avoid wasting memory for variables that are
> larger than
> needed; besides, you're also using a signed type for a number that
> may not
> ever be less than zero.
> 
> 
> > +};
> > +
> > +static const struct mt8186_mck_div mck_div[MT8186_MCK_NUM] = {
> > +	[MT8186_I2S0_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S0_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV0,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV0_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV0_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV0_MASK,
> > +		.div_sft = APLL12_CK_DIV0_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S0_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S0_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S1_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S1_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV1,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV1_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV1_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV1_MASK,
> > +		.div_sft = APLL12_CK_DIV1_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S1_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S1_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S2_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S2_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV2,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV2_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV2_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV2_MASK,
> > +		.div_sft = APLL12_CK_DIV2_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S2_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S2_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_I2S4_MCK] = {
> > +		.m_sel_id = CLK_TOP_I2S4_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV4,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV4_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_2,
> > +		.div_mask_sft = APLL12_CK_DIV4_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV4_MASK,
> > +		.div_sft = APLL12_CK_DIV4_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_I2S4_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_I2S4_MCK_SEL_SFT,
> > +	},
> > +	[MT8186_TDM_MCK] = {
> > +		.m_sel_id = CLK_TOP_TDM_M_SEL,
> > +		.div_clk_id = CLK_TOP_APLL12_DIV_TDM,
> > +		.div_pdn_reg = CLK_AUDDIV_0,
> > +		.div_pdn_mask_sft = APLL12_DIV_TDM_PDN_MASK_SFT,
> > +		.div_reg = CLK_AUDDIV_3,
> > +		.div_mask_sft = APLL12_CK_DIV_TDM_MASK_SFT,
> > +		.div_mask = APLL12_CK_DIV_TDM_MASK,
> > +		.div_sft = APLL12_CK_DIV_TDM_SFT,
> > +		.div_apll_sel_reg = CLK_AUDDIV_0,
> > +		.div_apll_sel_mask_sft = APLL_TDM_MCK_SEL_MASK_SFT,
> > +		.div_apll_sel_sft = APLL_TDM_MCK_SEL_SFT,
> > +	},
> > +};
> > +
> > +int mt8186_mck_enable(struct mtk_base_afe *afe, int mck_id, int
> > rate)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int apll = mt8186_get_apll_by_rate(afe, rate);
> > +	int apll_clk_id = apll == MT8186_APLL1 ?
> > +			  CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;
> > +	int m_sel_id = mck_div[mck_id].m_sel_id;
> > +	int div_clk_id = mck_div[mck_id].div_clk_id;
> > +	int ret;
> > +
> > +	/* select apll */
> > +	if (m_sel_id >= 0) {
> > +		ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), clk_prepare_enable %s
> > fail %d\n",
> > +				 __func__, aud_clks[m_sel_id], ret);
> 
> dev_err()
> 
> > +			return ret;
> > +		}
> > +		ret = clk_set_parent(afe_priv->clk[m_sel_id],
> > +				     afe_priv->clk[apll_clk_id]);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), clk_set_parent %s-%s
> > fail %d\n",
> > +				 __func__, aud_clks[m_sel_id],
> > +				aud_clks[apll_clk_id], ret);
> 
> again
> 
> > +			return ret;
> > +		}
> > +	}
> > +
> > +	/* enable div, set rate */
> > +	ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s(), clk_prepare_enable %s fail
> > %d\n",
> > +			 __func__, aud_clks[div_clk_id], ret);
> 
> again
> 
> > +		return ret;
> > +	}
> > +	ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);
> > +	if (ret) {
> > +		dev_info(afe->dev, "%s(), clk_set_rate %s, rate %d,
> > fail %d\n",
> > +			 __func__, aud_clks[div_clk_id],
> > +			 rate, ret);
> 
> again - and this fits in two lines.
> 
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_mck_disable(struct mtk_base_afe *afe, int mck_id)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int m_sel_id = mck_div[mck_id].m_sel_id;
> > +	int div_clk_id = mck_div[mck_id].div_clk_id;
> > +
> > +	clk_disable_unprepare(afe_priv->clk[div_clk_id]);
> > +	if (m_sel_id >= 0)
> > +		clk_disable_unprepare(afe_priv->clk[m_sel_id]);
> > +}
> > +
> > +int mt8186_init_clock(struct mtk_base_afe *afe)
> > +{
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct device_node *of_node = afe->dev->of_node;
> > +	int i = 0;
> > +
> > +	 mt8186_audsys_clk_register(afe);
> 
> Fix indentation please
> 
> > +
> > +	afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM,
> > sizeof(*afe_priv->clk),
> > +				     GFP_KERNEL);
> > +	if (!afe_priv->clk)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < CLK_NUM; i++) {
> > +		afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
> > +		if (IS_ERR(afe_priv->clk[i])) {
> > +			dev_info(afe->dev, "%s devm_clk_get %s fail,
> > ret %ld\n",
> > +				 __func__,
> > +				 aud_clks[i], PTR_ERR(afe_priv-
> > >clk[i]));
> > +			afe_priv->clk[i] = NULL;
> > +		}
> > +	}
> > +
> > +	afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node,
> > +							       "mediate
> > k,apmixedsys");
> > +	if (IS_ERR(afe_priv->apmixedsys)) {
> > +		dev_err(afe->dev, "%s() Cannot find apmixedsys
> > controller: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->apmixedsys));
> > +		return PTR_ERR(afe_priv->apmixedsys);
> > +	}
> > +
> > +	afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node,
> > +							     "mediatek,
> > topckgen");
> > +	if (IS_ERR(afe_priv->topckgen)) {
> > +		dev_err(afe->dev, "%s() Cannot find topckgen
> > controller: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->topckgen));
> > +		return PTR_ERR(afe_priv->topckgen);
> > +	}
> > +
> > +	afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node,
> > +							     "mediatek,
> > infracfg");
> > +	if (IS_ERR(afe_priv->infracfg)) {
> > +		dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n",
> > +			__func__, PTR_ERR(afe_priv->infracfg));
> > +		return PTR_ERR(afe_priv->infracfg);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +void mt8186_deinit_clock(struct mtk_base_afe *afe)
> > +{
> > +	mt8186_audsys_clk_unregister(afe);
> > +}
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > new file mode 100644
> > index 000000000000..3ce7a9a24d4a
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-clk.h
> > @@ -0,0 +1,210 @@
> > +/* SPDX-License-Identifier: GPL-2.0
> > + *
> > + * mt8186-afe-clk.h  --  Mediatek 8186 afe clock ctrl definition
> > + *
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > + */
> > +
> > +#ifndef _MT8186_AFE_CLOCK_CTRL_H_
> > +#define _MT8186_AFE_CLOCK_CTRL_H_
> > +
> > +#define PERI_BUS_DCM_CTRL 0x0074
> > +#define MODULE_SW_CG_1_STA 0x0094
> > +#define MODULE_SW_CG_2_STA 0x00ac
> > +#define CLK_CFG_7 0x0080
> > +#define CLK_CFG_8 0x0090
> > +#define CLK_CFG_11 0x00c0
> > +#define CLK_CFG_12 0x00d0
> > +#define CLK_CFG_13 0x00e0
> > +#define CLK_CFG_15 0x0100
> > +#define AP_PLL_CON3 0x0014
> > +#define APLL1_CON4 0x0328
> > +#define APLL1_TUNER_CON0 0x0040
> > +#define APLL2_CON4 0x033c
> > +#define APLL2_TUNER_CON0 0x0044
> > +
> > +#define AP_PLL_CON5 0x0014
> > +#define APLL1_CON0 0x02c0
> > +#define APLL1_CON1 0x02c4
> > +#define APLL1_CON2 0x02c8
> > +#define APLL1_CON3 0x02cc
> > +#define APLL1_PWR_CON0 0x02d0
> > +
> > +#define APLL2_CON0 0x02d4
> > +#define APLL2_CON1 0x02d8
> > +#define APLL2_CON2 0x02dc
> > +#define APLL2_CON3 0x02e0
> > +#define APLL2_PWR_CON0 0x02e4
> > +
> > +#define APMIXEDSYS_MAX_LENGTH APLL2_PWR_CON0
> > +
> > +#define CLK_CFG_6 0x0080
> > +#define CLK_AUDDIV_0 0x0320
> > +#define CLK_AUDDIV_1 0x0324
> > +#define CLK_AUDDIV_2 0x0328
> > +#define CKSYS_AUD_TOP_CFG 0x032c
> > +#define CKSYS_AUD_TOP_MON 0x0330
> > +#define CLK_AUDDIV_3 0x0334
> > +
> > +#define CLK_MAX_LENGTH CLK_AUDDIV_3
> > +
> > +/* CLK_CFG_6 */
> > +#define CLK_AUD_INTBUS_SEL_SFT              16
> > +#define CLK_AUD_INTBUS_SEL_MASK             0x3
> > +#define CLK_AUD_INTBUS_SEL_MASK_SFT         (0x3 << 16)
> 
> #define CLK_AUD_INTBUS_SEL_MASK_SFT		GENMASK(23, 22)
> 
> > +
> > +/* CLK_AUDDIV_0 */
> > +#define APLL12_DIV0_PDN_SFT                0
> > +#define APLL12_DIV0_PDN_MASK               0x1
> > +#define APLL12_DIV0_PDN_MASK_SFT           (0x1 << 0)
> 
> BIT() macro please
> 
> #define APLL12_DIV0_PDN_MASK_SFT		BIT(0)
> 
> also, using tabulations instead of spaces is nicer.
> 
> > +#define APLL12_DIV1_PDN_SFT                1
> > +#define APLL12_DIV1_PDN_MASK               0x1
> > +#define APLL12_DIV1_PDN_MASK_SFT           (0x1 << 1)
> 
> Of course, BIT() macro again, here and everywhere else applicable.
> 
> > +#define APLL12_DIV2_PDN_SFT                2
> > +#define APLL12_DIV2_PDN_MASK               0x1
> > +#define APLL12_DIV2_PDN_MASK_SFT           (0x1 << 2)
> > +#define APLL12_DIV4_PDN_SFT                3
> > +#define APLL12_DIV4_PDN_MASK               0x1
> > +#define APLL12_DIV4_PDN_MASK_SFT           (0x1 << 3)
> > +#define APLL12_DIV_TDM_PDN_SFT             4
> > +#define APLL12_DIV_TDM_PDN_MASK            0x1
> > +#define APLL12_DIV_TDM_PDN_MASK_SFT        (0x1 << 4)
> > +#define APLL_I2S0_MCK_SEL_SFT              16
> > +#define APLL_I2S0_MCK_SEL_MASK             0x1
> > +#define APLL_I2S0_MCK_SEL_MASK_SFT         (0x1 << 16)
> > +#define APLL_I2S1_MCK_SEL_SFT              17
> > +#define APLL_I2S1_MCK_SEL_MASK             0x1
> > +#define APLL_I2S1_MCK_SEL_MASK_SFT         (0x1 << 17)
> > +#define APLL_I2S2_MCK_SEL_SFT              18
> > +#define APLL_I2S2_MCK_SEL_MASK             0x1
> > +#define APLL_I2S2_MCK_SEL_MASK_SFT         (0x1 << 17)
> > +#define APLL_I2S4_MCK_SEL_SFT              19
> > +#define APLL_I2S4_MCK_SEL_MASK             0x1
> > +#define APLL_I2S4_MCK_SEL_MASK_SFT         (0x1 << 19)
> > +#define APLL_TDM_MCK_SEL_SFT               20
> > +#define APLL_TDM_MCK_SEL_MASK              0x1
> > +#define APLL_TDM_MCK_SEL_MASK_SFT          (0x1 << 20)
> > +
> > +/* CLK_AUDDIV_2 */
> > +#define APLL12_CK_DIV0_SFT                 0
> > +#define APLL12_CK_DIV0_MASK                0xff
> > +#define APLL12_CK_DIV0_MASK_SFT            (0xff << 0)
> 
> GENMASK(7, 0)
> 
> > +#define APLL12_CK_DIV1_SFT                 8
> > +#define APLL12_CK_DIV1_MASK                0xff
> > +#define APLL12_CK_DIV1_MASK_SFT            (0xff << 8)
> 
> GENMASK(15, 8)
> 
> > +#define APLL12_CK_DIV2_SFT                 16
> > +#define APLL12_CK_DIV2_MASK                0xff
> > +#define APLL12_CK_DIV2_MASK_SFT            (0xff << 16)
> 
> Fix all the others too :))
> 
> > +#define APLL12_CK_DIV4_SFT                 24
> > +#define APLL12_CK_DIV4_MASK                0xff
> > +#define APLL12_CK_DIV4_MASK_SFT            (0xff << 24)
> > +
> > +/* CLK_AUDDIV_3 */
> > +#define APLL12_CK_DIV_TDM_SFT              0
> > +#define APLL12_CK_DIV_TDM_MASK             0xff
> > +#define APLL12_CK_DIV_TDM_MASK_SFT         (0xff << 0)
> > +
> > +/* AUD_TOP_CFG */
> > +#define AUD_TOP_CFG_SFT                    0
> > +#define AUD_TOP_CFG_MASK                   0xffffffff
> > +#define AUD_TOP_CFG_MASK_SFT               (0xffffffff << 0)
> 
> This is GENMASK(31, 0) for both MASK and MASK_SFT
> 
> > +
> > +/* AUD_TOP_MON */
> > +#define AUD_TOP_MON_SFT                    0
> > +#define AUD_TOP_MON_MASK                   0xffffffff
> > +#define AUD_TOP_MON_MASK_SFT               (0xffffffff << 0)
> 
> same here
> 
> 
> 
> Regards,
> Angelo
Jiaxin Yu (俞家鑫) March 3, 2022, 3:30 p.m. UTC | #17
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch add gpio control for all audio interface separately.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-afe-gpio.c | 210
> > ++++++++++++++++++++
> >   sound/soc/mediatek/mt8186/mt8186-afe-gpio.h |  19 ++
> >   2 files changed, 229 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> > b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> > new file mode 100644
> > index 000000000000..6faec5c95bf3
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.c
> > @@ -0,0 +1,210 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// mt8186-afe-gpio.c  --  Mediatek 8186 afe gpio ctrl
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/gpio.h>
> > +#include <linux/pinctrl/consumer.h>
> > +
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-gpio.h"
> > +
> > +struct pinctrl *aud_pinctrl;
> > +
> > +enum mt8186_afe_gpio {
> > +	MT8186_AFE_GPIO_CLK_MOSI_OFF,
> > +	MT8186_AFE_GPIO_CLK_MOSI_ON,
> > +	MT8186_AFE_GPIO_CLK_MISO_OFF,
> > +	MT8186_AFE_GPIO_CLK_MISO_ON,
> > +	MT8186_AFE_GPIO_DAT_MISO_OFF,
> > +	MT8186_AFE_GPIO_DAT_MISO_ON,
> > +	MT8186_AFE_GPIO_DAT_MOSI_OFF,
> > +	MT8186_AFE_GPIO_DAT_MOSI_ON,
> > +	MT8186_AFE_GPIO_I2S0_OFF,
> > +	MT8186_AFE_GPIO_I2S0_ON,
> > +	MT8186_AFE_GPIO_I2S1_OFF,
> > +	MT8186_AFE_GPIO_I2S1_ON,
> > +	MT8186_AFE_GPIO_I2S2_OFF,
> > +	MT8186_AFE_GPIO_I2S2_ON,
> > +	MT8186_AFE_GPIO_I2S3_OFF,
> > +	MT8186_AFE_GPIO_I2S3_ON,
> > +	MT8186_AFE_GPIO_TDM_OFF,
> > +	MT8186_AFE_GPIO_TDM_ON,
> > +	MT8186_AFE_GPIO_PCM_OFF,
> > +	MT8186_AFE_GPIO_PCM_ON,
> > +	MT8186_AFE_GPIO_GPIO_NUM
> > +};
> > +
> > +struct audio_gpio_attr {
> > +	const char *name;
> > +	bool gpio_prepare;
> > +	struct pinctrl_state *gpioctrl;
> > +};
> > +
> > +static struct audio_gpio_attr aud_gpios[MT8186_AFE_GPIO_GPIO_NUM]
> > = {
> > +	[MT8186_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_CLK_MISO_OFF] = {"aud_clk_miso_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_CLK_MISO_ON] = {"aud_clk_miso_on", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
> > +	[MT8186_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
> > +	[MT8186_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
> > +	[MT8186_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false,
> > NULL},
> > +	[MT8186_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
> > +	[MT8186_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
> > +	[MT8186_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
> > +	[MT8186_AFE_GPIO_PCM_OFF] = {"aud_gpio_pcm_off", false, NULL},
> > +	[MT8186_AFE_GPIO_PCM_ON] = {"aud_gpio_pcm_on", false, NULL},
> > +};
> > +
> > +static DEFINE_MUTEX(gpio_request_mutex);
> > +
> > +int mt8186_afe_gpio_init(struct device *dev)
> > +{
> > +	int ret;
> > +	int i = 0;
> > +
> > +	aud_pinctrl = devm_pinctrl_get(dev);
> > +	if (IS_ERR(aud_pinctrl)) {
> > +		ret = PTR_ERR(aud_pinctrl);
> > +		dev_info(dev, "%s(), ret %d, cannot get
> > aud_pinctrl!\n",
> > +			 __func__, ret);
> 
> dev_err()
> ... and return ret.
> 
> > +		return -ENODEV;
> > +	}
> > +
> > +	for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
> > +		aud_gpios[i].gpioctrl =
> > pinctrl_lookup_state(aud_pinctrl,
> > +							     aud_gpios[
> > i].name);
> > +		if (IS_ERR(aud_gpios[i].gpioctrl)) {
> > +			ret = PTR_ERR(aud_gpios[i].gpioctrl);
> > +			dev_info(dev, "%s(), pinctrl_lookup_state %s
> > fail, ret %d\n",
> > +				 __func__, aud_gpios[i].name, ret);
> 
> dev_err()
> 
> P.S.: I think that this function should return ret, at this point, to
> avoid
>        unexpected behavior.

Because we maybe don't need to config all of audio interface gpio in
dtsi. for example, we may only use I2S0/I2S1 instead of I2S3/I2S4, so
there only config I2S0/I2S1's pinctrl in dtsi. So I think there only
need dev_info() as a reminder. How do you suggest for it?

> 
> 
> > +		} else {
> > +			aud_gpios[i].gpio_prepare = true;
> > +		}
> > +	}
> > +
> > +	/* gpio status init */
> > +	mt8186_afe_gpio_request(dev, false, MT8186_DAI_ADDA, 0);
> > +	mt8186_afe_gpio_request(dev, false, MT8186_DAI_ADDA, 1);
> > +
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL_GPL(mt8186_afe_gpio_init);
> > +
> > +static int mt8186_afe_gpio_select(struct device *dev,
> > +				  enum mt8186_afe_gpio type)
> > +{
> > +	int ret = 0;
> > +
> > +	if (type < 0 || type >= MT8186_AFE_GPIO_GPIO_NUM) {
> > +		dev_info(dev, "%s(), error, invalid gpio type %d\n",
> > +			 __func__, type);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (!aud_gpios[type].gpio_prepare) {
> > +		dev_info(dev, "%s(), error, gpio type %d not
> > prepared\n",
> > +			 __func__, type);
> > +		return -EIO;
> > +	}
> > +
> > +	ret = pinctrl_select_state(aud_pinctrl,
> > +				   aud_gpios[type].gpioctrl);
> > +	if (ret)
> > +		dev_info(dev, "%s(), error, can not set gpio type
> > %d\n",
> > +			 __func__, type);
> > +
> > +	return ret;
> 
> Please change it like so:
> 
> 	if (ret) {
> 		dev_err(dev, "Failed to select picntrl state for type
> %d\n", type);
> 		return ret;
> 	}
> 
> 	return 0;
> 
> > +}
> > +
> > +static int mt8186_afe_gpio_adda_dl(struct device *dev, bool
> > enable)
> > +{
> > +	if (enable) {
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_CLK_MOSI_ON);
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_DAT_MOSI_ON);
> > +	} else {
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_DAT_MOSI_OFF);
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_CLK_MOSI_OFF);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_afe_gpio_adda_ul(struct device *dev, bool
> > enable)
> > +{
> > +	if (enable) {
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_CLK_MISO_ON);
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_DAT_MISO_ON);
> > +	} else {
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_DAT_MISO_OFF);
> > +		mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_CLK_MISO_OFF);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +int mt8186_afe_gpio_request(struct device *dev, bool enable,
> > +			    int dai, int uplink)
> > +{
> 
> I think that it's more readable and even shorter if you do:
> 
> 	enum mt8186_afe_gpio sel;
> 
> 	int ret = -EINVAL;
> 
> 
> 
> 	mutex_lock(&gpio_request_mutex);
> 
> 
> 
> 	switch (dai) {
> 
> 	case MT8186_DAI_ADDA:
> 		if (uplink)
> 			ret = mt8186_afe_gpio_adda_ul(dev, enable);
> 		else
> 			ret = mt8186_afe_gpio_adda_dl(dev, enable);
> 		goto unlock;
> 	case MT8186_DAI_I2S_0:
> 
> 		sel = enable ? MT8186_AFE_GPIO_I2S0_ON :
> MT8186_AFE_GPIO_I2S0_OFF;
> 
> 		break;
> 
> 	case MT8186_DAI_I2S_1:
> 
> 		sel = enable ? MT8186_AFE_GPIO_I2S1_ON :
> MT8186_AFE_GPIO_I2S1_OFF;
> 
> 		break;
> 
> 
> 
> 	.................... all other cases ................
> 
> 	default:
> 
> 		dev_err(dev, "invalid dai %d\n", dai);
> 
> 		goto unlock;
> 
> 	}
> 
> 
> 	ret = mt8186_afe_gpio_select(dev, sel);
> 
> 
> unlock:
> 
> 	mutex_unlock(&gpio_request_mutex);
> 
> 	return ret;
> }
> 
> > +	mutex_lock(&gpio_request_mutex);
> > +	switch (dai) {
> > +	case MT8186_DAI_ADDA:
> > +		if (uplink)
> > +			mt8186_afe_gpio_adda_ul(dev, enable);
> > +		else
> > +			mt8186_afe_gpio_adda_dl(dev, enable);
> > +		break;
> > +	case MT8186_DAI_I2S_0:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S0_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S0_OFF);
> > +		break;
> > +	case MT8186_DAI_I2S_1:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S1_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S1_OFF);
> > +		break;
> > +	case MT8186_DAI_I2S_2:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S2_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S2_OFF);
> > +		break;
> > +	case MT8186_DAI_I2S_3:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S3_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_I2S3_OFF);
> > +		break;
> > +	case MT8186_DAI_TDM_IN:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_TDM_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_TDM_OFF);
> > +		break;
> > +	case MT8186_DAI_PCM:
> > +		if (enable)
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_PCM_ON);
> > +		else
> > +			mt8186_afe_gpio_select(dev,
> > MT8186_AFE_GPIO_PCM_OFF);
> > +		break;
> > +	default:
> > +		mutex_unlock(&gpio_request_mutex);
> > +		dev_info(dev, "%s(), invalid dai %d\n", __func__, dai);
> > +		return -EINVAL;
> > +	}
> > +	mutex_unlock(&gpio_request_mutex);
> > +	return 0;
> > +}
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> > b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> > new file mode 100644
> > index 000000000000..1ddc27838eb1
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-gpio.h
> > @@ -0,0 +1,19 @@
> > +/* SPDX-License-Identifier: GPL-2.0
> > + *
> > + * mt6833-afe-gpio.h  --  Mediatek 6833 afe gpio ctrl definition
> > + *
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > + */
> > +
> > +#ifndef _MT8186_AFE_GPIO_H_
> > +#define _MT8186_AFE_GPIO_H_
> > +
> > +struct mtk_base_afe;
> > +
> > +int mt8186_afe_gpio_init(struct device *dev);
> > +
> > +int mt8186_afe_gpio_request(struct device *dev, bool enable,
> > +			    int dai, int uplink);
> > +
> > +#endif
> 
>
Jiaxin Yu (俞家鑫) March 3, 2022, 5:39 p.m. UTC | #18
On Thu, 2022-03-03 at 16:08 +0100, AngeloGioacchino Del Regno wrote:
> Il 03/03/22 15:10, Jiaxin Yu ha scritto:
> > On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno
> > wrote:
> > > Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > > > This patch adds mt8186 tdm dai driver.
> > > > 
> > > > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > > > ---
> > > >    sound/soc/mediatek/mt8186/mt8186-dai-tdm.c | 713
> > > > +++++++++++++++++++++
> > > >    1 file changed, 713 insertions(+)
> > > >    create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-
> > > > tdm.c
> > > > 
> > > > diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > > > b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > > > new file mode 100644
> > > > index 000000000000..28dd3661f0e0
> > > > --- /dev/null
> > > > +++ b/sound/soc/mediatek/mt8186/mt8186-dai-tdm.c
> > > > @@ -0,0 +1,713 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +//
> > > > +// MediaTek ALSA SoC Audio DAI TDM Control
> > > > +//
> > > > +// Copyright (c) 2022 MediaTek Inc.
> > > > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > > > +
> 
> ..snip..
> 
> > > > +
> > > > +static int mtk_dai_tdm_hw_params(struct snd_pcm_substream
> > > > *substream,
> > > > +				 struct snd_pcm_hw_params
> > > > *params,
> > > > +				 struct snd_soc_dai *dai)
> > > > +{
> > > > +	struct mtk_base_afe *afe =
> > > > snd_soc_dai_get_drvdata(dai);
> > > > +	struct mt8186_afe_private *afe_priv = afe-
> > > > >platform_priv;
> > > > +	int tdm_id = dai->id;
> > > > +	struct mtk_afe_tdm_priv *tdm_priv = afe_priv-
> > > > >dai_priv[tdm_id];
> > > > +	unsigned int tdm_mode = tdm_priv->tdm_mode;
> > > > +	unsigned int data_mode = tdm_priv->data_mode;
> > > > +	unsigned int rate = params_rate(params);
> > > > +	unsigned int channels = params_channels(params);
> > > > +	snd_pcm_format_t format = params_format(params);
> > > > +	unsigned int bit_width =
> > > > +		snd_pcm_format_physical_width(format);
> > > > +	unsigned int tdm_channels = (data_mode ==
> > > > TDM_DATA_ONE_PIN) ?
> > > > +		get_tdm_ch_per_sdata(tdm_mode, channels) : 2;
> > > > +	unsigned int lrck_width =
> > > > +		get_tdm_lrck_width(format, tdm_mode);
> > > > +	unsigned int tdm_con = 0;
> > > > +	bool slave_mode = tdm_priv->slave_mode;
> > > > +	bool lrck_inv = tdm_priv->lck_invert;
> > > > +	bool bck_inv = tdm_priv->bck_invert;
> > > > +	unsigned int ctrl_reg;
> > > > +	unsigned int ctrl_mask;
> > > > +	unsigned int tran_rate;
> > > > +	unsigned int tran_relatch_rate;
> > > > +
> > > > +	if (tdm_priv)
> > > > +		tdm_priv->rate = rate;
> > > > +	else
> > > > +		dev_info(afe->dev, "%s(), tdm_priv == NULL",
> > > > __func__);
> > > > +
> > > > +	tran_rate = mt8186_rate_transform(afe->dev, rate, dai-
> > > > >id);
> > > > +	tran_relatch_rate =
> > > > mt8186_tdm_relatch_rate_transform(afe->dev,
> > > > rate);
> > > > +
> > > > +	/* calculate mclk_rate, if not set explicitly */
> > > > +	if (!tdm_priv->mclk_rate) {
> > > > +		tdm_priv->mclk_rate = rate * tdm_priv-
> > > > >mclk_multiple;
> > > > +		mtk_dai_tdm_cal_mclk(afe,
> > > > +				     tdm_priv,
> > > > +				     tdm_priv->mclk_rate);
> > > > +	}
> > > > +
> > > > +	/* ETDM_IN1_CON0 */
> > > > +	tdm_con |= slave_mode <<
> > > > ETDM_IN1_CON0_REG_SLAVE_MODE_SFT;
> > > > +	tdm_con |= tdm_mode << ETDM_IN1_CON0_REG_FMT_SFT;
> > > > +	tdm_con |= (bit_width - 1) <<
> > > > ETDM_IN1_CON0_REG_BIT_LENGTH_SFT;
> > > > +	tdm_con |= (bit_width - 1) <<
> > > > ETDM_IN1_CON0_REG_WORD_LENGTH_SFT;
> > > > +	tdm_con |= (tdm_channels - 1) <<
> > > > ETDM_IN1_CON0_REG_CH_NUM_SFT;
> > > > +	/* default disable sync mode */
> > > > +	tdm_con |= 0 << ETDM_IN1_CON0_REG_SYNC_MODE_SFT;
> > > 
> > > 0 << (anything) == 0
> > > 
> > > (number |= 0) == number
> > > 
> > > Is this a mistake, or are you really doing nothing here?
> > > 
> > 
> > No, this is just to emphasize the need to set this bit to 0.
> > It really do nothing here, just link a reminder.
> > Can I keep this sentence?
> 
> If, in your judgement, it is very important to have a reminder about
> that
> bit having to be unset, then add a comment in the code saying so.
> Don't simply comment out the statement as it is.
> 
> A good way would be something like
> /* sync mode bit has to be unset because this that reason, otherwise
> X happens */

I see, thanks for your kind advise.
> 
> > > 
> > > > +	/* relatch fix to h26m */
> > > > +	tdm_con |= 0 <<
> > > > ETDM_IN1_CON0_REG_RELATCH_1X_EN_SEL_DOMAIN_SFT;
> > > > +
> > > > +	ctrl_reg = ETDM_IN1_CON0;
> > > > +	ctrl_mask = ETDM_IN_CON0_CTRL_MASK;
> > > > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask,
> > > > tdm_con);
> > > > +
> > > > +	/* ETDM_IN1_CON1 */
> > > > +	tdm_con = 0;
> > > > +	tdm_con |= 0 << ETDM_IN1_CON1_REG_LRCK_AUTO_MODE_SFT;
> > > > +	tdm_con |= 1 << ETDM_IN1_CON1_PINMUX_MCLK_CTRL_OE_SFT;
> > > > +	tdm_con |= (lrck_width - 1) <<
> > > > ETDM_IN1_CON1_REG_LRCK_WIDTH_SFT;
> > > > +
> > > > +	ctrl_reg = ETDM_IN1_CON1;
> > > > +	ctrl_mask = ETDM_IN_CON1_CTRL_MASK;
> > > > +	regmap_update_bits(afe->regmap, ctrl_reg, ctrl_mask,
> > > > tdm_con);
> > > 
> > > You don't need the ctrl_reg, nor ctrl_mask variables...
> > 
> > I was trying to avoid a line of more than 80 words, so I shortened
> > the
> > number of words through variables.
> > 
> 
> Yes, I know, I did understand what you were trying to do...
> ...but it's fine to go past 80: in this case this would be 88
> columns,
> which is still ok to have!
> 
> And note, this is the case with all of similar calls present in this
> function,
> that's why I said that you don't need these two variables! :)
> 
> Thank you,
> Angelo
Ok, I got it. This function will be corrected in the next version.

Thank you.
Jiaxin.Yu


> 
>
Jiaxin Yu (俞家鑫) March 5, 2022, 4:24 a.m. UTC | #19
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > Mt6366 is a new version of mt6358, and they are same about audio
> > part.
> > So we can reuse the driver of mt6358.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> 
> Hello Jiaxin,
> I'm sorry but this commit makes very little sense.
> 
> If you want to advertise MT6366 support, please write a note and/or
> a new compatible string inside of the mt6358 driver (and dt-
> bindings),
> then, please drop this commit.
> 

Hello angelogioacchino,

Thank you for your advice.

If I add a new compatible string inside of the mt6358 driver and dt-
bindings, then the machine driver which want to use mt6366 should
select SND_SOC_MT6358.

like below:

config SND_SOC_MT8186_MT6366_DA7219_MAX98357
	tristate "ASoC Audio driver for MT8186 with DA7219 MAX98357A
codec"
 	depends on I2C && GPIOLIB
 	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
 	select SND_SOC_MT6366   ==> SND_SOC_MT6358
	...

I just doubt it's enough to make sense. I originally wanted to put this
relationship in the sound/soc/codecs layer. So that this relationship
is not perceived by users(machine driver).
However, if the general practice is like this, I will adopt your
suggestion. Thank you again.

> 
> > ---
> >   sound/soc/codecs/Kconfig  | 8 ++++++++
> >   sound/soc/codecs/Makefile | 1 +
> >   2 files changed, 9 insertions(+)
> > 
> > diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> > index 8fa24783ce01..6631094678f5 100644
> > --- a/sound/soc/codecs/Kconfig
> > +++ b/sound/soc/codecs/Kconfig
> > @@ -132,6 +132,7 @@ config SND_SOC_ALL_CODECS
> >   	imply SND_SOC_MT6351
> >   	imply SND_SOC_MT6358
> >   	imply SND_SOC_MT6359
> > +	imply SND_SOC_MT6366
> >   	imply SND_SOC_MT6660
> >   	imply SND_SOC_NAU8315
> >   	imply SND_SOC_NAU8540
> > @@ -1888,6 +1889,13 @@ config SND_SOC_MT6359_ACCDET
> >   	  for ASoC codec soc-jack detection mechanism.
> >   	  Select N if you don't have jack on board.
> >   
> > +config SND_SOC_MT6366
> > +	tristate "MediaTek MT6366 Codec"
> > +	depends on MTK_PMIC_WRAP
> > +	help
> > +	  Enable support for the platform which uses MT6366 as
> > +	  external codec device.
> > +
> >   config SND_SOC_MT6660
> >   	tristate "Mediatek MT6660 Speaker Amplifier"
> >   	depends on I2C
> > diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> > index 42d00aa4ee46..1279684feaf0 100644
> > --- a/sound/soc/codecs/Makefile
> > +++ b/sound/soc/codecs/Makefile
> > @@ -465,6 +465,7 @@ obj-$(CONFIG_SND_SOC_MT6351)	+= snd-soc-
> > mt6351.o
> >   obj-$(CONFIG_SND_SOC_MT6358)	+= snd-soc-mt6358.o
> >   obj-$(CONFIG_SND_SOC_MT6359)	+= snd-soc-mt6359.o
> >   obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o
> > +obj-$(CONFIG_SND_SOC_MT6366)	+= snd-soc-mt6358.o
> >   obj-$(CONFIG_SND_SOC_MT6660)	+= snd-soc-mt6660.o
> >   obj-$(CONFIG_SND_SOC_NAU8315)   += snd-soc-nau8315.o
> >   obj-$(CONFIG_SND_SOC_NAU8540)   += snd-soc-nau8540.o
> 
>
Jiaxin Yu (俞家鑫) March 5, 2022, 8:58 a.m. UTC | #20
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:42, Jiaxin Yu ha scritto:
> > This patch adds support for mt8186 board with mt6366, da7219 and
> > max98357.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   .../mt8186/mt8186-mt6366-da7219-max98357.c    | 910
> > ++++++++++++++++++
> >   1 file changed, 910 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-
> > da7219-max98357.c
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-
> > max98357.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-
> > max98357.c
> > new file mode 100644
> > index 000000000000..6ba53b8d1e46
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
> > @@ -0,0 +1,910 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// mt8186-mt6366-da7219-max98357.c
> > +//	--  MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +//
> > +
> > +#include <linux/input.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
> > +#include <sound/pcm_params.h>
> > +#include <sound/soc.h>
> > +
> > +#include "../../codecs/da7219-aad.h"
> > +#include "../../codecs/da7219.h"
> > +#include "../../codecs/mt6358.h"
> > +#include "../common/mtk-afe-platform-driver.h"
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-afe-gpio.h"
> > +
> > +#define DA7219_CODEC_DAI "da7219-hifi"
> > +#define DA7219_DEV_NAME "da7219.5-001a"
> > +
> > +struct mt8186_mt6366_da7219_max98357_priv {
> > +	struct snd_soc_jack headset_jack, hdmi_jack;
> > +};
> > +
> > +static struct snd_soc_codec_conf mt6366_codec_conf[] = {
> > +	{
> > +		.dlc = COMP_CODEC_CONF("mt6358-sound"),
> > +		.name_prefix = "Mt6366",
> > +	},
> > +};
> > +
> > +static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd)
> > +{
> > +	struct mt8186_mt6366_da7219_max98357_priv *priv =
> > +		snd_soc_card_get_drvdata(rtd->card);
> > +	struct snd_soc_jack *jack = &priv->headset_jack;
> > +	struct snd_soc_component *cmpnt_codec =
> > +		asoc_rtd_to_codec(rtd, 0)->component;
> > +	int ret;
> > +
> > +	/* Enable Headset and 4 Buttons Jack detection */
> > +	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
> > +				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
> > +				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
> > +				    SND_JACK_BTN_3 | SND_JACK_LINEOUT,
> > +				    jack, NULL, 0);
> > +	if (ret) {
> > +		dev_err(rtd->dev, "Headset Jack creation failed: %d\n",
> > ret);
> > +		return ret;
> > +	}
> > +
> > +	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
> > +	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
> > +	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
> > +	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
> > +
> > +	da7219_aad_jack_det(cmpnt_codec, &priv->headset_jack);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream
> > *substream,
> > +				       struct snd_pcm_hw_params
> > *params)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd =
> > asoc_substream_to_rtd(substream);
> > +	struct snd_soc_dai *codec_dai;
> > +	unsigned int rate = params_rate(params);
> > +	unsigned int mclk_fs_ratio = 256;
> > +	unsigned int mclk_fs = rate * mclk_fs_ratio;
> > +	unsigned int freq;
> > +	int ret = 0, j;
> > +
> > +	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
> > +				     mclk_fs, SND_SOC_CLOCK_OUT);
> > +	if (ret < 0)
> > +		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
> 
> Does it really make sense to go on after this failure?
> 
> > +
> > +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
> > +		if (!strcmp(codec_dai->component->name,
> > DA7219_DEV_NAME)) {
> > +			ret = snd_soc_dai_set_sysclk(codec_dai,
> > +						     DA7219_CLKSRC_MCLK
> > ,
> > +						     mclk_fs,
> > +						     SND_SOC_CLOCK_IN);
> > +			if (ret < 0)
> > +				dev_err(rtd->dev, "failed to set
> > sysclk\n");
> > +
> 
> I think that going on past this wouldn't make sense as well, as it
> may result
> in unexpected behavior... just return a failure here

Yes, it is.
> 
> > +			if ((rate % 8000) == 0)
> > +				freq = DA7219_PLL_FREQ_OUT_98304;
> > +			else
> > +				freq = DA7219_PLL_FREQ_OUT_90316;
> > +
> > +			ret = snd_soc_dai_set_pll(codec_dai, 0,
> > +						  DA7219_SYSCLK_PLL_SRM
> > ,
> > +						  0, freq);
> > +			if (ret)
> > +				dev_err(rtd->dev, "failed to start PLL:
> > %d\n",
> > +					ret);
> 
> and here
Yes, you are right.

> 
> > +		}
> > +	}
> > +
> 
> So, you've covered all failure cases already, for which, you can
> simply
> return 0 here.
Yes, it is.

> 
> > +	return ret;
> > +}
> > +
> > +static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream
> > *substream)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd =
> > asoc_substream_to_rtd(substream);
> > +	struct snd_soc_dai *codec_dai;
> > +	int ret = 0, j;
> > +
> > +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
> > +		if (!strcmp(codec_dai->component->name,
> > DA7219_DEV_NAME)) {
> > +			ret = snd_soc_dai_set_pll(codec_dai,
> > +						  0,
> > DA7219_SYSCLK_MCLK, 0, 0);
> > +			if (ret < 0) {
> > +				dev_err(rtd->dev, "failed to stop PLL:
> > %d\n",
> > +					ret);
> > +				break;
> > +			}
> > +		}
> > +	}
> > +
> > +	return ret;
> > +}
> > +
> > +static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
> > +	.hw_params = mt8186_da7219_i2s_hw_params,
> > +	.hw_free = mt8186_da7219_i2s_hw_free,
> > +};
> > +
> > +static int mt8186_mt6366_hdmi_init(struct snd_soc_pcm_runtime
> > *rtd)
> > +{
> > +	struct snd_soc_component *cmpnt_codec =
> > +		asoc_rtd_to_codec(rtd, 0)->component;
> > +	struct mt8186_mt6366_da7219_max98357_priv *priv =
> > +		snd_soc_card_get_drvdata(rtd->card);
> > +	int ret;
> > +
> > +	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack",
> > SND_JACK_LINEOUT,
> > +				    &priv->hdmi_jack, NULL, 0);
> > +	if (ret) {
> > +		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n",
> > ret);
> > +		return ret;
> > +	}
> > +
> > +	return snd_soc_component_set_jack(cmpnt_codec, &priv-
> > >hdmi_jack, NULL);
> > +}
> > +
> > +static int mt8186_mt6366_init(struct snd_soc_pcm_runtime *rtd)
> > +{
> > +	struct snd_soc_component *cmpnt_afe =
> > +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> > +	struct snd_soc_component *cmpnt_codec =
> > +		asoc_rtd_to_codec(rtd, 0)->component;
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt_afe);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
> > +	int ret;
> > +
> > +	/* set mtkaif protocol */
> > +	mt6358_set_mtkaif_protocol(cmpnt_codec,
> > +				   MT6358_MTKAIF_PROTOCOL_1);
> > +	afe_priv->mtkaif_protocol = MT6358_MTKAIF_PROTOCOL_1;
> > +
> > +	ret = snd_soc_dapm_sync(dapm);
> > +	if (ret) {
> > +		dev_info(rtd->dev, "failed to snd_soc_dapm_sync\n");
> 
> dev_err()
> 
> > +		return ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
> > *rtd,
> > +				      struct snd_pcm_hw_params *params)
> > +{
> > +	struct snd_interval *channels = hw_param_interval(params,
> > +		SNDRV_PCM_HW_PARAM_CHANNELS);
> > +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
> > +
> 
> dev_dbg()
> 
> > +	/* fix BE i2s channel to 2 channel */
> > +	channels->min = 2;
> > +	channels->max = 2;
> > +
> > +	/* fix BE i2s format to S32_LE, clean param mask first */
> > +	snd_mask_reset_range(hw_param_mask(params,
> > SNDRV_PCM_HW_PARAM_FORMAT),
> > +			     0, (__force unsigned
> > int)SNDRV_PCM_FORMAT_LAST);
> > +
> > +	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_hdmi_i2s_hw_params_fixup(struct
> > snd_soc_pcm_runtime *rtd,
> > +					   struct snd_pcm_hw_params
> > *params)
> > +{
> > +	struct snd_interval *channels = hw_param_interval(params,
> > +		SNDRV_PCM_HW_PARAM_CHANNELS);
> > +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
> > +
> 
> dev_dbg()
> 
> > +	/* fix BE i2s channel to 2 channel */
> > +	channels->min = 2;
> > +	channels->max = 2;
> > +
> > +	/* fix BE i2s format to S24_LE, clean param mask first */
> > +	snd_mask_reset_range(hw_param_mask(params,
> > SNDRV_PCM_HW_PARAM_FORMAT),
> > +			     0, (__force unsigned
> > int)SNDRV_PCM_FORMAT_LAST);
> > +
> > +	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
> > +
> > +	return 0;
> > +}
> 

Ok, I will use this code which is really more concise.

> Besides, I would do the following instead:
> 
> static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
> 
> 				  struct snd_pcm_hw_params *params,
> 
> 				  snd_pcm_format_t fmt)
> 
> {
> 
> 	struct snd_interval *channels = hw_param_interval(params,
> 
> 		SNDRV_PCM_HW_PARAM_CHANNELS);
> 
> 	dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__);
> 
> 
> 
> 	/* fix BE i2s channel to 2 channel */
> 
> 	channels->min = 2;
> 
> 	channels->max = 2;
> 
> 
> 
> 	/* fix BE i2s format to S32_LE, clean param mask first */
> 
> 	snd_mask_reset_range(hw_param_mask(params,
> SNDRV_PCM_HW_PARAM_FORMAT),
> 
> 			     0, (__force unsigned
> int)SNDRV_PCM_FORMAT_LAST);
> 
> 
> 
> 	params_set_format(params, fmt);
> 
> 
> 
> 	return 0;
> 
> }
> 
> 
> 
> static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
> *rtd,
> 
> 				      struct snd_pcm_hw_params *params)
> 
> {
> 
> 	return mt8186_hw_params_fixup(rtd, params,
> SNDRV_PCM_FORMAT_S32_LE);
> 
> }
> 
> 
> 
> static int mt8186_hdmi_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
> *rtd,
> 
> 					   struct snd_pcm_hw_params
> *params)
> 
> {
> 
> 	return mt8186_hw_params_fixup(rtd, params,
> SNDRV_PCM_FORMAT_S24_LE);
> 
> }
> 
> ... this reduces code duplication!
> 
> > +
> > +/* FE */
> > +SND_SOC_DAILINK_DEFS(playback1,
> > +		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
> > +		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
> > +		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
> 
> 
> ..snip..
> 
> > +static int mt8186_mt6366_da7219_max98357_dev_probe(struct
> > platform_device *pdev)
> > +{
> > +	struct snd_soc_card *card =
> > &mt8186_mt6366_da7219_max98357_soc_card;
> > +	struct snd_soc_dai_link *dai_link;
> > +	struct mt8186_mt6366_da7219_max98357_priv *priv;
> > +	struct device_node *platform_node, *hdmi_codec;
> > +	int ret, i;
> > +
> > +	dev_info(&pdev->dev, "%s(), ++\n", __func__);
> > +
> > +	card->dev = &pdev->dev;
> > +
> > +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
> > +	if (!priv)
> > +		return -ENOMEM;
> > +
> > +	platform_node = of_parse_phandle(pdev->dev.of_node,
> > +					 "mediatek,platform", 0);
> > +	if (!platform_node) {
> > +		dev_info(&pdev->dev,
> > +			 "Property 'platform' missing or invalid\n");
> 
> 	if (!platform_node)
> 		return dev_err_probe(&pdev->dev, -EINVAL,
> 				    "mediatek,platform missing or
> invalid\n");
> 
> > +		return -EINVAL;
got err_platform_node;
> > +	}
> > +
> > +	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
> > +				      "mediatek,hdmi-codec", 0);
> > +	if (!hdmi_codec) {
> > +		dev_info(&pdev->dev,
> > +			 "Property 'hdmi' missing or invalid\n");
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
Should I of_node_put(platform_node) befor return?

goto err_hdmi_node;


> > +
> > +	for_each_card_prelinks(card, i, dai_link) {
> > +		if (dai_link->platforms->name)
> > +			continue;
> > +
> > +		if (hdmi_codec && strcmp(dai_link->name, "I2S3") == 0)
> > {
> > +			dai_link->codecs->of_node = hdmi_codec;
> > +			dai_link->ignore = 0;
> > +		}
> > +
> > +		dai_link->platforms->of_node = platform_node;
> > +	}
> > +
> > +	snd_soc_card_set_drvdata(card, priv);
> > +
> > +	/* init gpio */
> > +	ret = mt8186_afe_gpio_init(&pdev->dev);
> > +	if (ret)
> > +		dev_info(&pdev->dev, "init gpio error\n");
> 
> dev_err() and goto end;
Yes, goto err_init_gpio and of_node_put for hdmi_codec and
platform_node.
> 
> > +
> > +	dev_info(&pdev->dev, "%s(), devm_snd_soc_register_card\n",
> > __func__);
> > +	ret = devm_snd_soc_register_card(&pdev->dev, card);
> > +	if (ret)
> > +		dev_info(&pdev->dev, "%s snd_soc_register_card fail
> > %d\n",
> > +			 __func__, ret);
> 
> dev_err_probe()
> 
> end:
> 
err_init_gpio:
> > +	of_node_put(hdmi_codec);
err_hdmi_node:
> > +	of_node_put(platform_node);
> > +
err_platform_node:
> > +	return ret;
> > +}
> > +
> > +#if IS_ENABLED(CONFIG_OF)
> > +static const struct of_device_id
> > mt8186_mt6366_da7219_max98357_dt_match[] = {
> > +	{.compatible =
> > "mediatek,mt8186_mt6366_da7219_max98357_sound",},
> > +	{}
> > +};
> > +#endif
> > +
> > +static struct platform_driver mt8186_mt6366_da7219_max98357_driver
> > = {
> > +	.driver = {
> > +		.name = "mt8186_mt6366_da7219_max98357",
> > +#if IS_ENABLED(CONFIG_OF)
> > +		.of_match_table =
> > mt8186_mt6366_da7219_max98357_dt_match,
> > +#endif
> > +		.pm = &snd_soc_pm_ops,
> > +	},
> > +	.probe = mt8186_mt6366_da7219_max98357_dev_probe,
> > +};
> > +
> > +module_platform_driver(mt8186_mt6366_da7219_max98357_driver);
> > +
> > +/* Module information */
> > +MODULE_DESCRIPTION("MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine
> > driver");
> > +MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
> > +MODULE_LICENSE("GPL v2");
> > +MODULE_ALIAS("mt8186_mt6366_da7219_max98357 soc card");
> 
>
Jiaxin Yu (俞家鑫) March 5, 2022, 9:10 a.m. UTC | #21
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:42, Jiaxin Yu ha scritto:
> > This patch adds mt8186 platform and affiliated driver.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/Kconfig                    |   44 +
> >   sound/soc/mediatek/Makefile                   |    1 +
> >   sound/soc/mediatek/mt8186/Makefile            |   21 +
> >   sound/soc/mediatek/mt8186/mt8186-afe-common.h |  245 ++
> >   .../soc/mediatek/mt8186/mt8186-afe-control.c  |  261 ++
> >   sound/soc/mediatek/mt8186/mt8186-afe-pcm.c    | 3029
> > +++++++++++++++
> >   .../mediatek/mt8186/mt8186-interconnection.h  |   69 +
> >   .../soc/mediatek/mt8186/mt8186-misc-control.c | 1728 +++++++++
> >   sound/soc/mediatek/mt8186/mt8186-reg.h        | 3433
> > +++++++++++++++++
> >   9 files changed, 8831 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/Makefile
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-common.h
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-control.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-
> > interconnection.h
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-misc-
> > control.c
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-reg.h
> > 
> > diff --git a/sound/soc/mediatek/Kconfig
> > b/sound/soc/mediatek/Kconfig
> > index 3b1ddea26a9e..d3528bdbb00a 100644
> > --- a/sound/soc/mediatek/Kconfig
> > +++ b/sound/soc/mediatek/Kconfig
> > @@ -152,6 +152,50 @@ config SND_SOC_MT8183_DA7219_MAX98357A
> >   	  Select Y if you have such device.
> >   	  If unsure select "N".
> >   
> > +config SND_SOC_MT8186
> > +	tristate "ASoC support for Mediatek MT8186 chip"
> > +	depends on ARCH_MEDIATEK || COMPILE_TEST
> > +	depends on COMMON_CLK
> > +	select SND_SOC_MEDIATEK
> > +	select MFD_SYSCON if SND_SOC_MT6366
> > +	help
> > +	  This adds ASoC driver for Mediatek MT8186 boards
> > +	  that can be used with other codecs.
> > +	  Select Y if you have such device.
> > +	  If unsure select "N".
> > +
> > +config SND_SOC_MT8186_MT6366_DA7219_MAX98357
> > +	tristate "ASoC Audio driver for MT8186 with DA7219 MAX98357A
> > codec"
> > +	depends on I2C && GPIOLIB
> > +	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
> > +	select SND_SOC_MT6366
> > +	select SND_SOC_MAX98357A
> > +	select SND_SOC_DA7219
> > +	select SND_SOC_BT_SCO
> > +	select SND_SOC_DMIC
> > +	select SND_SOC_HDMI_CODEC
> > +	help
> > +	  This adds ASoC driver for Mediatek MT8186 boards
> > +	  with the MT6366 DA7219 MAX98357A codecs.
> > +	  Select Y if you have such device.
> > +	  If unsure select "N".
> > +
> > +config SND_SOC_MT8186_MT6366_RT1019_RT5682S
> > +	tristate "ASoC Audio driver for MT8186 with RT1019 RT5682S
> > codec"
> > +	depends on I2C && GPIOLIB
> > +	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
> > +	select SND_SOC_MT6366
> > +	select SND_SOC_RT1015P
> > +	select SND_SOC_RT5682S
> > +	select SND_SOC_BT_SCO
> > +	select SND_SOC_DMIC
> > +	select SND_SOC_HDMI_CODEC
> > +	help
> > +	  This adds ASoC driver for Mediatek MT8186 boards
> > +	  with the MT6366 RT1019 RT5682S codecs.
> > +	  Select Y if you have such device.
> > +	  If unsure select "N".
> > +
> >   config SND_SOC_MTK_BTCVSD
> >   	tristate "ALSA BT SCO CVSD/MSBC Driver"
> >   	help
> > diff --git a/sound/soc/mediatek/Makefile
> > b/sound/soc/mediatek/Makefile
> > index 34778ca12106..5571c640a288 100644
> > --- a/sound/soc/mediatek/Makefile
> > +++ b/sound/soc/mediatek/Makefile
> > @@ -4,5 +4,6 @@ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
> >   obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
> >   obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
> >   obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
> > +obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
> >   obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
> >   obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
> > diff --git a/sound/soc/mediatek/mt8186/Makefile
> > b/sound/soc/mediatek/mt8186/Makefile
> > new file mode 100644
> > index 000000000000..9f3bead9cdf8
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/Makefile
> > @@ -0,0 +1,21 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +# platform driver
> > +snd-soc-mt8186-afe-objs := \
> > +	mt8186-afe-pcm.o \
> > +	mt8186-audsys-clk.o \
> > +	mt8186-afe-clk.o \
> > +	mt8186-afe-gpio.o \
> > +	mt8186-dai-adda.o \
> > +	mt8186-afe-control.o \
> > +	mt8186-dai-i2s.o \
> > +	mt8186-dai-hw-gain.o \
> > +	mt8186-dai-pcm.o \
> > +	mt8186-dai-src.o \
> > +	mt8186-dai-hostless.o \
> > +	mt8186-dai-tdm.o \
> > +	mt8186-misc-control.o
> > +
> > +obj-$(CONFIG_SND_SOC_MT8186) += snd-soc-mt8186-afe.o
> > +obj-$(CONFIG_SND_SOC_MT8186_MT6366_DA7219_MAX98357) += mt8186-
> > mt6366-da7219-max98357.o
> > +obj-$(CONFIG_SND_SOC_MT8186_MT6366_RT1019_RT5682S) += mt8186-
> > mt6366-rt1019-rt5682s.o
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-common.h
> > b/sound/soc/mediatek/mt8186/mt8186-afe-common.h
> > new file mode 100644
> > index 000000000000..b2b50faa3887
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-common.h
> > @@ -0,0 +1,245 @@
> > +/* SPDX-License-Identifier: GPL-2.0
> > + *
> > + * mt8186-afe-common.h  --  Mediatek 8186 audio driver definitions
> > + *
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > + */
> > +
> > +#ifndef _MT_8186_AFE_COMMON_H_
> > +#define _MT_8186_AFE_COMMON_H_
> > +#include <sound/soc.h>
> > +#include <linux/list.h>
> > +#include <linux/regmap.h>
> > +#include "mt8186-reg.h"
> > +#include "../common/mtk-base-afe.h"
> > +
> > +#if IS_ENABLED(CONFIG_MTK_AEE_FEATURE)
> > +#define AUDIO_AEE(message) \
> > +	(aee_kernel_exception_api(__FILE__, \
> > +				  __LINE__, \
> > +				  DB_OPT_FTRACE, message, \
> > +				  "audio assert"))
> > +#else
> > +#define AUDIO_AEE(message) WARN_ON(true)
> > +#endif
> 
> There is no such AEE upstream, please remove this block entirely.
> 
Ok, got it.

> ...snip...
> 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-control.c
> > b/sound/soc/mediatek/mt8186/mt8186-afe-control.c
> > new file mode 100644
> > index 000000000000..cb863716a74b
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-control.c
> > @@ -0,0 +1,261 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include "mt8186-afe-common.h"
> > +#include <linux/pm_runtime.h>
> > +
> > +enum {
> > +	MTK_AFE_RATE_8K = 0,
> 
> You just need to define the first one as zero and you don't need to
> assign numbers to the others, since they are sequential.
> Please fix.
> 
Ok, got it.

> > +	MTK_AFE_RATE_11K = 1,
> > +	MTK_AFE_RATE_12K = 2,
> > +	MTK_AFE_RATE_384K = 3,
> > +	MTK_AFE_RATE_16K = 4,
> > +	MTK_AFE_RATE_22K = 5,
> > +	MTK_AFE_RATE_24K = 6,
> > +	MTK_AFE_RATE_352K = 7,
> > +	MTK_AFE_RATE_32K = 8,
> > +	MTK_AFE_RATE_44K = 9,
> > +	MTK_AFE_RATE_48K = 10,
> > +	MTK_AFE_RATE_88K = 11,
> > +	MTK_AFE_RATE_96K = 12,
> > +	MTK_AFE_RATE_176K = 13,
> > +	MTK_AFE_RATE_192K = 14,
> > +	MTK_AFE_RATE_260K = 15,
> > +};
> > +
> > +enum {
> > +	MTK_AFE_PCM_RATE_8K = 0,
> > +	MTK_AFE_PCM_RATE_16K = 1,
> > +	MTK_AFE_PCM_RATE_32K = 2,
> > +	MTK_AFE_PCM_RATE_48K = 3,
> 
> same here
> 
> > +};
> > +
> > +enum {
> > +	MTK_AFE_TDM_RATE_8K = 0,
> > +	MTK_AFE_TDM_RATE_12K = 1,
> > +	MTK_AFE_TDM_RATE_16K = 2,
> > +	MTK_AFE_TDM_RATE_24K = 3,
> > +	MTK_AFE_TDM_RATE_32K = 4,
> > +	MTK_AFE_TDM_RATE_48K = 5,
> > +	MTK_AFE_TDM_RATE_64K = 6,
> > +	MTK_AFE_TDM_RATE_96K = 7,
> > +	MTK_AFE_TDM_RATE_128K = 8,
> > +	MTK_AFE_TDM_RATE_192K = 9,
> > +	MTK_AFE_TDM_RATE_256K = 10,
> > +	MTK_AFE_TDM_RATE_384K = 11,
> > +	MTK_AFE_TDM_RATE_11K = 16,
> > +	MTK_AFE_TDM_RATE_22K = 17,
> > +	MTK_AFE_TDM_RATE_44K = 18,
> > +	MTK_AFE_TDM_RATE_88K = 19,
> > +	MTK_AFE_TDM_RATE_176K = 20,
> > +	MTK_AFE_TDM_RATE_352K = 21, > +};
> > +
> > +enum {
> > +	MTK_AFE_TDM_RELATCH_RATE_8K = 0,
> > +	MTK_AFE_TDM_RELATCH_RATE_11K = 1,
> > +	MTK_AFE_TDM_RELATCH_RATE_12K = 2,
> > +	MTK_AFE_TDM_RELATCH_RATE_16K = 4,
> > +	MTK_AFE_TDM_RELATCH_RATE_22K = 5,
> > +	MTK_AFE_TDM_RELATCH_RATE_24K = 6,
> > +	MTK_AFE_TDM_RELATCH_RATE_32K = 8,
> > +	MTK_AFE_TDM_RELATCH_RATE_44K = 9,
> > +	MTK_AFE_TDM_RELATCH_RATE_48K = 10,
> > +	MTK_AFE_TDM_RELATCH_RATE_88K = 13,
> > +	MTK_AFE_TDM_RELATCH_RATE_96K = 14,
> > +	MTK_AFE_TDM_RELATCH_RATE_176K = 17,
> > +	MTK_AFE_TDM_RELATCH_RATE_192K = 18,
> > +	MTK_AFE_TDM_RELATCH_RATE_352K = 21,
> > +	MTK_AFE_TDM_RELATCH_RATE_384K = 22,
> > +};
> > +
> > +unsigned int mt8186_general_rate_transform(struct device *dev,
> > +					   unsigned int rate)
> > +{
> > +	switch (rate) {
> > +	case 8000:
> > +		return MTK_AFE_RATE_8K;
> > +	case 11025:
> > +		return MTK_AFE_RATE_11K;
> > +	case 12000:
> > +		return MTK_AFE_RATE_12K;
> > +	case 16000:
> > +		return MTK_AFE_RATE_16K;
> > +	case 22050:
> > +		return MTK_AFE_RATE_22K;
> > +	case 24000:
> > +		return MTK_AFE_RATE_24K;
> > +	case 32000:
> > +		return MTK_AFE_RATE_32K;
> > +	case 44100:
> > +		return MTK_AFE_RATE_44K;
> > +	case 48000:
> > +		return MTK_AFE_RATE_48K;
> > +	case 88200:
> > +		return MTK_AFE_RATE_88K;
> > +	case 96000:
> > +		return MTK_AFE_RATE_96K;
> > +	case 176400:
> > +		return MTK_AFE_RATE_176K;
> > +	case 192000:
> > +		return MTK_AFE_RATE_192K;
> > +	case 260000:
> > +		return MTK_AFE_RATE_260K;
> > +	case 352800:
> > +		return MTK_AFE_RATE_352K;
> > +	case 384000:
> > +		return MTK_AFE_RATE_384K;
> > +	default:
> > +		dev_info(dev, "%s(), rate %u invalid, use %d!!!\n",
> > +			 __func__,
> > +			 rate, MTK_AFE_RATE_48K);
> 
> dev_err(); ... and don't return here, but...
> 
> > +		return MTK_AFE_RATE_48K;
> > +	}
> 
> 
> ... return here, outside of the switch.
> 
> > +}
> > +
> > +static unsigned int tdm_rate_transform(struct device *dev,
> > +				       unsigned int rate)
> > +{
> > +	switch (rate) {
> > +	case 8000:
> > +		return MTK_AFE_TDM_RATE_8K;
> > +	case 11025:
> > +		return MTK_AFE_TDM_RATE_11K;
> > +	case 12000:
> > +		return MTK_AFE_TDM_RATE_12K;
> > +	case 16000:
> > +		return MTK_AFE_TDM_RATE_16K;
> > +	case 22050:
> > +		return MTK_AFE_TDM_RATE_22K;
> > +	case 24000:
> > +		return MTK_AFE_TDM_RATE_24K;
> > +	case 32000:
> > +		return MTK_AFE_TDM_RATE_32K;
> > +	case 44100:
> > +		return MTK_AFE_TDM_RATE_44K;
> > +	case 48000:
> > +		return MTK_AFE_TDM_RATE_48K;
> > +	case 64000:
> > +		return MTK_AFE_TDM_RATE_64K;
> > +	case 88200:
> > +		return MTK_AFE_TDM_RATE_88K;
> > +	case 96000:
> > +		return MTK_AFE_TDM_RATE_96K;
> > +	case 128000:
> > +		return MTK_AFE_TDM_RATE_128K;
> > +	case 176400:
> > +		return MTK_AFE_TDM_RATE_176K;
> > +	case 192000:
> > +		return MTK_AFE_TDM_RATE_192K;
> > +	case 256000:
> > +		return MTK_AFE_TDM_RATE_256K;
> > +	case 352800:
> > +		return MTK_AFE_TDM_RATE_352K;
> > +	case 384000:
> > +		return MTK_AFE_TDM_RATE_384K;
> > +	default:
> > +		dev_info(dev, "%s(), rate %u invalid, use %d!!!\n",
> > +			 __func__,
> > +			 rate, MTK_AFE_TDM_RATE_48K);
> > +		return MTK_AFE_TDM_RATE_48K;
> 
> ditto.
> here and for all the other instances.
> 
> > +	}
> > +}
> > +
> 
> ...snip...
> 
> > +}
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> > b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> > new file mode 100644
> > index 000000000000..e1e17a934245
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c
> > @@ -0,0 +1,3029 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// Mediatek ALSA SoC AFE platform driver for 8186
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/delay.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/module.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset.h>
> > +#include <sound/soc.h>
> > +
> > +#include "../common/mtk-afe-platform-driver.h"
> > +#include "../common/mtk-afe-fe-dai.h"
> > +
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-afe-gpio.h"
> > +#include "mt8186-interconnection.h"
> > +
> > +static const struct snd_pcm_hardware mt8186_afe_hardware = {
> > +	.info = (SNDRV_PCM_INFO_MMAP |
> > +		 SNDRV_PCM_INFO_INTERLEAVED |
> > +		 SNDRV_PCM_INFO_MMAP_VALID),
> > +	.formats = (SNDRV_PCM_FMTBIT_S16_LE |
> > +		    SNDRV_PCM_FMTBIT_S24_LE |
> > +		    SNDRV_PCM_FMTBIT_S32_LE),
> > +	.period_bytes_min = 96,
> > +	.period_bytes_max = 4 * 48 * 1024,
> > +	.periods_min = 2,
> > +	.periods_max = 256,
> > +	.buffer_bytes_max = 4 * 48 * 1024,
> > +	.fifo_size = 0,
> > +};
> > +
> > +static int mt8186_fe_startup(struct snd_pcm_substream *substream,
> > +			     struct snd_soc_dai *dai)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct snd_pcm_runtime *runtime = substream->runtime;
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> > +	const struct snd_pcm_hardware *mtk_afe_hardware = afe-
> > >mtk_afe_hardware;
> > +	int ret;
> > +
> > +	memif->substream = substream;
> > +
> > +	snd_pcm_hw_constraint_step(substream->runtime, 0,
> > +				   SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
> > 16);
> > +
> > +	snd_soc_set_runtime_hwparams(substream, mtk_afe_hardware);
> > +
> > +	ret = snd_pcm_hw_constraint_integer(runtime,
> > +					    SNDRV_PCM_HW_PARAM_PERIODS)
> > ;
> > +	if (ret < 0)
> > +		dev_info(afe->dev, "snd_pcm_hw_constraint_integer
> > failed\n");
> 
> 	if (ret < 0) {
> 		dev_err .....
> 		return ret;
> 	}
> 
> > +
> > +	/* dynamic allocate irq to memif */
> > +	if (memif->irq_usage < 0) {
> > +		int irq_id = mtk_dynamic_irq_acquire(afe);
> > +
> > +		if (irq_id != afe->irqs_size) {
> > +			/* link */
> > +			memif->irq_usage = irq_id;
> > +		} else {
> > +			dev_info(afe->dev, "%s() error: no more asys
> > irq\n",
> > +				 __func__);
> > +			ret = -EBUSY;
> 
> 			return -EBUSY;
> > +		}
> > +	}
> > +
> 
> 	return 0;
> 
> > +	return ret;
> > +}
> > +
> > +static void mt8186_fe_shutdown(struct snd_pcm_substream
> > *substream,
> > +			       struct snd_soc_dai *dai)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> > +	int irq_id = memif->irq_usage;
> > +
> > +	memif->substream = NULL;
> > +	afe_priv->irq_cnt[id] = 0;
> > +	afe_priv->xrun_assert[id] = 0;
> > +
> > +	if (!memif->const_irq) {
> > +		mtk_dynamic_irq_release(afe, irq_id);
> > +		memif->irq_usage = -1;
> > +		memif->substream = NULL;
> > +	}
> > +}
> > +
> > +static int mt8186_fe_hw_params(struct snd_pcm_substream
> > *substream,
> > +			       struct snd_pcm_hw_params *params,
> > +			       struct snd_soc_dai *dai)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +	unsigned int channels = params_channels(params);
> > +	unsigned int rate = params_rate(params);
> > +	int ret;
> > +
> > +	ret = mtk_afe_fe_hw_params(substream, params, dai);
> > +	if (ret)
> 
> 		return ret;
> > +		goto exit;
> > +
> > +	/* channel merge configuration, enable control is in UL5_IN_MUX
> > */
> > +	if (id == MT8186_MEMIF_VUL3) {
> > +		int update_cnt = 8;
> > +		unsigned int val = 0;
> > +		unsigned int mask = 0;
> > +		int fs_mode = mt8186_rate_transform(afe->dev, rate,
> > id);
> > +
> > +		/* set rate, channel, update cnt, disable sgen */
> > +		val = fs_mode << CM1_FS_SELECT_SFT |
> > +			(channels - 1) << CHANNEL_MERGE0_CHNUM_SFT |
> > +			update_cnt << CHANNEL_MERGE0_UPDATE_CNT_SFT |
> > +			0 << CHANNEL_MERGE0_DEBUG_MODE_SFT |
> > +			0 << CM1_DEBUG_MODE_SEL_SFT;
> 
> 0 << number == 0!!!
> 
> > +		mask = CM1_FS_SELECT_MASK_SFT |
> > +			CHANNEL_MERGE0_CHNUM_MASK_SFT |
> > +			CHANNEL_MERGE0_UPDATE_CNT_MASK_SFT |
> > +			CHANNEL_MERGE0_DEBUG_MODE_MASK_SFT |
> > +			CM1_DEBUG_MODE_SEL_MASK_SFT;
> > +		regmap_update_bits(afe->regmap, AFE_CM1_CON, mask,
> > val);
> > +	}
> > +
> 
> 	return 0;
> 
> ... and remove the label, as it's not needed
> > +exit:
> > +	return ret;
> > +}
> > +
> > +static int mt8186_fe_hw_free(struct snd_pcm_substream *substream,
> > +			     struct snd_soc_dai *dai)
> > +{
> > +	int ret;
> > +
> > +	ret = mtk_afe_fe_hw_free(substream, dai);
> > +	if (ret)
> > +		goto exit;
> > +
> > +	/* wait for some platform related operation */
> > +exit:
> > +	return ret;
> > +}
> > +
> > +static int mt8186_fe_trigger(struct snd_pcm_substream *substream,
> > int cmd,
> > +			     struct snd_soc_dai *dai)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct snd_pcm_runtime * const runtime = substream->runtime;
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> > +	int irq_id = memif->irq_usage;
> > +	struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> > +	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> > +	unsigned int counter = runtime->period_size;
> > +	unsigned int rate = runtime->rate;
> > +	int fs;
> > +	int ret;
> > +
> > +	dev_info(afe->dev, "%s(), %s cmd %d, irq_id %d\n",
> > +		 __func__, memif->data->name, cmd, irq_id);
> 
> 
> dev_dbg()
> 
> > +
> > +	switch (cmd) {
> > +	case SNDRV_PCM_TRIGGER_START:
> > +	case SNDRV_PCM_TRIGGER_RESUME:
> > +		ret = mtk_memif_set_enable(afe, id);
> 
> 		if (ret) {
> 			dev_err ........
> 			return ret;
> 		}
> 
> 		/*
> 		 * for small latency record
> 		 * ul memif need read some data before irq enable
> 		 */
> 		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
> 		    ((runtime->period_size * 1000) / rate) <= 10)
> 				usleep_range(300, 310);
> 
> 
> > +		/*
> > +		 * for small latency record
> > +		 * ul memif need read some data before irq enable
> > +		 */
> > +		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
> > +			if ((runtime->period_size * 1000) / rate <= 10)
> > +				usleep_range(300, 310);
> > +		}
> > +
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), error, id %d, memif
> > enable, ret %d\n",
> > +				 __func__, id, ret);
> > +			return ret;
> > +		}
> > +
> > +		/* set irq counter */
> > +		if (afe_priv->irq_cnt[id] > 0)
> > +			counter = afe_priv->irq_cnt[id];
> > +
> > +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> > +				   irq_data->irq_cnt_maskbit
> > +				   << irq_data->irq_cnt_shift,
> > +				   counter << irq_data->irq_cnt_shift);
> > +
> > +		/* set irq fs */
> > +		fs = afe->irq_fs(substream, runtime->rate);
> > +
> 
> empty line: remove.
> 
> > +		if (fs < 0)
> > +			return -EINVAL;
> > +
> > +		regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
> > +				   irq_data->irq_fs_maskbit
> > +				   << irq_data->irq_fs_shift,
> > +				   fs << irq_data->irq_fs_shift);
> > +
> > +		/* enable interrupt */
> > +		if (runtime->stop_threshold != ~(0U))
> > +			regmap_update_bits(afe->regmap,
> > +					   irq_data->irq_en_reg,
> > +					   1 << irq_data->irq_en_shift,
> > +					   1 << irq_data-
> > >irq_en_shift);
> > +		return 0;
> > +	case SNDRV_PCM_TRIGGER_STOP:
> > +	case SNDRV_PCM_TRIGGER_SUSPEND:
> > +		if (afe_priv->xrun_assert[id] > 0) {
> > +			if (substream->stream ==
> > SNDRV_PCM_STREAM_CAPTURE) {
> > +				int avail =
> > snd_pcm_capture_avail(runtime);
> > +
> > +				if (avail >= runtime->buffer_size) {
> > +					dev_info(afe->dev, "%s(), id
> > %d, xrun assert\n",
> > +						 __func__, id);
> > +				}
> > +			}
> > +		}
> > +
> > +		ret = mtk_memif_set_disable(afe, id);
> > +		if (ret) {
> > +			dev_info(afe->dev, "%s(), error, id %d, memif
> > enable, ret %d\n",
> > +				 __func__, id, ret);
> 
> dev_err()
> 
> > +		}
> > +
> > +		/* disable interrupt */
> > +		if (runtime->stop_threshold != ~(0U))
> > +			regmap_update_bits(afe->regmap,
> > +					   irq_data->irq_en_reg,
> > +					   1 << irq_data->irq_en_shift,
> > +					   0 << irq_data-
> > >irq_en_shift);
> > +
> > +		/* clear pending IRQ */
> > +		regmap_write(afe->regmap, irq_data->irq_clr_reg,
> > +			     1 << irq_data->irq_clr_shift);
> > +		return ret;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +}
> > +
> > +static int mt8186_memif_fs(struct snd_pcm_substream *substream,
> > +			   unsigned int rate)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct snd_soc_component *component =
> > +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(component);
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +
> > +	return mt8186_rate_transform(afe->dev, rate, id);
> > +}
> > +
> > +static int mt8186_get_dai_fs(struct mtk_base_afe *afe,
> > +			     int dai_id, unsigned int rate)
> > +{
> > +	return mt8186_rate_transform(afe->dev, rate, dai_id);
> > +}
> > +
> > +static int mt8186_irq_fs(struct snd_pcm_substream *substream,
> > unsigned int rate)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct snd_soc_component *component =
> > +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(component);
> > +
> > +	return mt8186_general_rate_transform(afe->dev, rate);
> > +}
> > +
> > +static int mt8186_get_memif_pbuf_size(struct snd_pcm_substream
> > *substream)
> > +{
> > +	struct snd_pcm_runtime *runtime = substream->runtime;
> > +
> > +	if ((runtime->period_size * 1000) / runtime->rate > 10)
> > +		return MT8186_MEMIF_PBUF_SIZE_256_BYTES;
> > +	else
> 
> drop "else"... and just return MT8186_MEMIF_PBUF_SIZE_32_BYTES
> 
> > +		return MT8186_MEMIF_PBUF_SIZE_32_BYTES;
> > +}
> > +
> > +static int mt8186_fe_prepare(struct snd_pcm_substream *substream,
> > +			     struct snd_soc_dai *dai)
> > +{
> > +	struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > +	struct snd_pcm_runtime * const runtime = substream->runtime;
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	int id = asoc_rtd_to_cpu(rtd, 0)->id;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[id];
> > +	int irq_id = memif->irq_usage;
> > +	struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> > +	const struct mtk_base_irq_data *irq_data = irqs->irq_data;
> > +	unsigned int counter = runtime->period_size;
> > +	int fs;
> > +	int ret;
> > +
> > +	ret = mtk_afe_fe_prepare(substream, dai);
> > +	if (ret)
> 
> 		return ret;
> 
> > +		goto exit;
> > +
> > +	/* set irq counter */
> > +	regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> > +			   irq_data->irq_cnt_maskbit
> > +			   << irq_data->irq_cnt_shift,
> > +			   counter << irq_data->irq_cnt_shift);
> > +
> > +	/* set irq fs */
> > +	fs = afe->irq_fs(substream, runtime->rate);
> > +
> > +	if (fs < 0)
> > +		return -EINVAL;
> > +
> > +	regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
> > +			   irq_data->irq_fs_maskbit
> > +			   << irq_data->irq_fs_shift,
> > +			   fs << irq_data->irq_fs_shift);
> > +exit:
> 
> unneeded label, and return 0;
> 
> > +	return ret;
> > +}
> > +
> 
> ..snip..
> 
> > +static int mt8186_irq_cnt1_set(struct snd_kcontrol *kcontrol,
> > +			       struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int memif_num = MT8186_PRIMARY_MEMIF;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
> > +	int irq_id = memif->irq_usage;
> > +	int irq_cnt = afe_priv->irq_cnt[memif_num];
> > +
> > +	dev_info(afe->dev, "%s(), irq_id %d, irq_cnt = %d, value =
> > %ld\n",
> > +		 __func__,
> > +		 irq_id, irq_cnt,
> > +		 ucontrol->value.integer.value[0]);
> 
> dev_dbg() - and fits in less lines.
> 
> > +
> > +	if (irq_cnt == ucontrol->value.integer.value[0])
> > +		return 0;
> > +
> > +	irq_cnt = ucontrol->value.integer.value[0];
> > +	afe_priv->irq_cnt[memif_num] = irq_cnt;
> > +
> > +	if (pm_runtime_status_suspended(afe->dev) || irq_id < 0) {
> > +		dev_info(afe->dev, "%s(), suspended || irq_id %d, not
> > set\n",
> > +			 __func__, irq_id);
> > +	} else {
> > +		struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> > +		const struct mtk_base_irq_data *irq_data = irqs-
> > >irq_data;
> > +
> > +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> > +				   irq_data->irq_cnt_maskbit
> > +				   << irq_data->irq_cnt_shift,
> > +				   irq_cnt << irq_data->irq_cnt_shift);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_irq_cnt2_get(struct snd_kcontrol *kcontrol,
> > +			       struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	ucontrol->value.integer.value[0] =
> > +		afe_priv->irq_cnt[MT8186_RECORD_MEMIF];
> > +	return 0;
> > +}
> > +
> > +static int mt8186_irq_cnt2_set(struct snd_kcontrol *kcontrol,
> > +			       struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int memif_num = MT8186_RECORD_MEMIF;
> > +	struct mtk_base_afe_memif *memif = &afe->memif[memif_num];
> > +	int irq_id = memif->irq_usage;
> > +	int irq_cnt = afe_priv->irq_cnt[memif_num];
> > +
> > +	dev_info(afe->dev, "%s(), irq_id %d, irq_cnt = %d, value =
> > %ld\n",
> > +		 __func__,
> > +		 irq_id, irq_cnt,
> > +		 ucontrol->value.integer.value[0]);
> 
> dev_dbg() - and fits in less lines.
> 
> > +
> > +	if (irq_cnt == ucontrol->value.integer.value[0])
> > +		return 0;
> > +
> > +	irq_cnt = ucontrol->value.integer.value[0];
> > +	afe_priv->irq_cnt[memif_num] = irq_cnt;
> > +
> > +	if (pm_runtime_status_suspended(afe->dev) || irq_id < 0) {
> > +		dev_info(afe->dev, "%s(), suspended || irq_id %d, not
> > set\n",
> > +			 __func__, irq_id);
> > +	} else {
> > +		struct mtk_base_afe_irq *irqs = &afe->irqs[irq_id];
> > +		const struct mtk_base_irq_data *irq_data = irqs-
> > >irq_data;
> > +
> > +		regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
> > +				   irq_data->irq_cnt_maskbit
> > +				   << irq_data->irq_cnt_shift,
> > +				   irq_cnt << irq_data->irq_cnt_shift);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> 
> 
> > +
> > +static irqreturn_t mt8186_afe_irq_handler(int irq_id, void *dev)
> > +{
> > +	struct mtk_base_afe *afe = dev;
> > +	struct mtk_base_afe_irq *irq;
> > +	unsigned int status;
> > +	unsigned int status_mcu;
> > +	unsigned int mcu_en;
> > +	int ret;
> > +	int i;
> > +
> > +	/* get irq that is sent to MCU */
> > +	regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
> 
> ret = regmap_read ....
> if (ret) ....
> 
> > +
> > +	ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
> > +	/* only care IRQ which is sent to MCU */
> > +	status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
> > +
> > +	if (ret || status_mcu == 0) {
> > +		dev_info(afe->dev, "%s(), irq status err, ret %d,
> > status 0x%x, mcu_en 0x%x\n",
> > +			 __func__, ret, status, mcu_en);
> 
> dev_err()
> 
> > +
> > +		goto err_irq;
> > +	}
> > +
> > +	for (i = 0; i < MT8186_MEMIF_NUM; i++) {
> > +		struct mtk_base_afe_memif *memif = &afe->memif[i];
> > +
> > +		if (!memif->substream)
> > +			continue;
> > +
> > +		if (memif->irq_usage < 0)
> > +			continue;
> > +
> > +		irq = &afe->irqs[memif->irq_usage];
> > +
> > +		if (status_mcu & (1 << irq->irq_data->irq_en_shift))
> > +			snd_pcm_period_elapsed(memif->substream);
> > +	}
> > +
> > +err_irq:
> > +	/* clear irq */
> > +	regmap_write(afe->regmap,
> > +		     AFE_IRQ_MCU_CLR,
> > +		     status_mcu);
> 
> fits in a single line.
> 
> > +
> > +	return IRQ_HANDLED;
> > +}
> > +
> > +static int mt8186_afe_runtime_suspend(struct device *dev)
> > +{
> > +	struct mtk_base_afe *afe = dev_get_drvdata(dev);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	unsigned int value = 0;
> > +	int ret;
> > +
> > +	if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
> > +		goto skip_regmap;
> > +
> > +	/* disable AFE */
> > +	regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
> > +
> > +	ret = regmap_read_poll_timeout(afe->regmap,
> > +				       AFE_DAC_MON,
> > +				       value,
> > +				       (value & AFE_ON_RETM_MASK_SFT)
> > == 0,
> > +				       20,
> > +				       1 * 1000 * 1000);
> > +	if (ret)
> > +		dev_info(afe->dev, "%s(), ret %d\n", __func__, ret);
> 
> dev_err()!!
> P.S.: Are you sure that we shouldn't return here?

No, this should return error, I will correct here.

> 
> > +
> > +	/* make sure all irq status are cleared */
> > +	regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, 0xffffffff);
> > +	regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, 0xffffffff);
> > +
> > +	/* reset sgen */
> > +	regmap_write(afe->regmap, AFE_SINEGEN_CON0, 0x0);
> > +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> > +			   INNER_LOOP_BACK_MODE_MASK_SFT,
> > +			   0x3f << INNER_LOOP_BACK_MODE_SFT);
> > +
> > +	/* cache only */
> > +	regcache_cache_only(afe->regmap, true);
> > +	regcache_mark_dirty(afe->regmap);
> > +
> > +skip_regmap:
> > +	mt8186_afe_disable_cgs(afe);
> > +	mt8186_afe_disable_clock(afe);
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_afe_runtime_resume(struct device *dev)
> > +{
> > +	struct mtk_base_afe *afe = dev_get_drvdata(dev);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int ret;
> > +
> > +	ret = mt8186_afe_enable_clock(afe);
> > +	if (ret)
> > +		return ret;
> > +
> > +	ret = mt8186_afe_enable_cgs(afe);
> > +	if (ret)
> > +		return ret;
> > +
> > +	if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
> > +		goto skip_regmap;
> > +
> > +	regcache_cache_only(afe->regmap, false);
> > +	regcache_sync(afe->regmap);
> > +
> > +	/* enable audio sys DCM for power saving */
> > +	regmap_update_bits(afe_priv->infracfg,
> > +			   PERI_BUS_DCM_CTRL, 0x1 << 29, 0x1 << 29);
> 
> BIT(29)
> 
> > +	regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, 0x1 << 29, 0x1
> > << 29);
> > +
> > +	/* force cpu use 8_24 format when writing 32bit data */
> > +	regmap_update_bits(afe->regmap, AFE_MEMIF_CON0,
> > +			   CPU_HD_ALIGN_MASK_SFT, 0 <<
> > CPU_HD_ALIGN_SFT);
> 
> 0 << number == 0, so write 0
> 
> > +
> > +	/* set all output port to 24bit */
> > +	regmap_write(afe->regmap, AFE_CONN_24BIT, 0xffffffff);
> > +	regmap_write(afe->regmap, AFE_CONN_24BIT_1, 0xffffffff);
> > +
> > +	/* enable AFE */
> > +	regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
> > +
> > +skip_regmap:
> > +	return 0;
> > +}
> 
> ..snip..
> 
> > +static int mt8186_afe_pcm_dev_probe(struct platform_device *pdev)
> > +{
> > +	struct mtk_base_afe *afe;
> > +	struct mt8186_afe_private *afe_priv;
> > +	struct resource *res;
> > +	struct reset_control *rstc;
> > +	struct device *dev = &pdev->dev;
> > +	int i, ret, irq_id;
> > +
> > +	dev_info(dev, "%s(), ++\n", __func__);
> 
> Drop this print.
> 
> > +
> > +	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(34));
> > +	if (ret)
> > +		return ret;
> > +
> > +	afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL);
> > +	if (!afe)
> > +		return -ENOMEM;
> > +	platform_set_drvdata(pdev, afe);
> > +
> > +	afe->platform_priv = devm_kzalloc(dev, sizeof(*afe_priv),
> > GFP_KERNEL);
> > +	if (!afe->platform_priv)
> > +		return -ENOMEM;
> > +
> > +	afe_priv = afe->platform_priv;
> > +	afe->dev = &pdev->dev;
> > +
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	afe->base_addr = devm_ioremap_resource(&pdev->dev, res);
> > +	if (IS_ERR(afe->base_addr))
> > +		return PTR_ERR(afe->base_addr);
> > +
> > +	dev_info(dev, "%s(), mt8186_init_clock\n", __func__);
> 
> Drop this print.
> 
> > +	/* init audio related clock */
> > +	ret = mt8186_init_clock(afe);
> > +	if (ret) {
> > +		dev_info(dev, "init clock error\n");
> 
> dev_err()
> 
> > +		return ret;
> > +	}
> > +
> > +	/* init memif */
> > +	afe->memif_32bit_supported = 0;
> > +	afe->memif_size = MT8186_MEMIF_NUM;
> > +	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe-
> > >memif),
> > +				  GFP_KERNEL);
> > +
> > +	if (!afe->memif)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < afe->memif_size; i++) {
> > +		afe->memif[i].data = &memif_data[i];
> > +		afe->memif[i].irq_usage = memif_irq_usage[i];
> > +		afe->memif[i].const_irq = 1;
> > +	}
> > +
> > +	mutex_init(&afe->irq_alloc_lock);	/* needed when dynamic irq
> > */
> > +
> > +	dev_info(dev, "%s(), init irq\n", __func__);
> 
> Drop this print.
> 
> > +
> > +	/* init irq */
> > +	afe->irqs_size = MT8186_IRQ_NUM;
> > +	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe-
> > >irqs),
> > +				 GFP_KERNEL);
> > +
> > +	if (!afe->irqs)
> > +		return -ENOMEM;
> > +
> > +	for (i = 0; i < afe->irqs_size; i++)
> > +		afe->irqs[i].irq_data = &irq_data[i];
> > +
> > +	dev_info(dev, "%s(), devm_request_irq\n", __func__);
> 
> Drop.
> 
> > +
> > +	/* request irq */
> > +	irq_id = platform_get_irq(pdev, 0);
> > +	if (irq_id <= 0) {
> > +		dev_info(dev, "%pOFn no irq found\n", dev->of_node);
> 
> 		return dev_err_probe(dev, irq_id < 0 ? irq_id : -ENXIO,
> 				     "no irq found");
> 
> > +		return irq_id < 0 ? irq_id : -ENXIO;
> > +	}
> > +	ret = devm_request_irq(dev, irq_id, mt8186_afe_irq_handler,
> > +			       IRQF_TRIGGER_NONE,
> > +			       "Afe_ISR_Handle", (void *)afe);
> > +	if (ret) {
> > +		dev_info(dev, "could not request_irq for
> > Afe_ISR_Handle\n");
> 
> return dev_err_probe(dev, ret, "could not request Afe_ISR_Handle
> irq\n");
> 
> > +		return ret;
> > +	}
> > +
> > +	ret = enable_irq_wake(irq_id);
> > +	if (ret < 0)
> > +		dev_info(dev, "enable_irq_wake %d err: %d\n", irq_id,
> > ret);
> 
> Isn't this a critical error?
> 		return dev_err_probe(.......
Yes it is, I will correct here that return dev_err_probe(...).

> 
> > +
> > +	/* init sub_dais */
> > +	INIT_LIST_HEAD(&afe->sub_dais);
> > +
> > +	for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
> > +		ret = dai_register_cbs[i](afe);
> > +		if (ret) {
> > +			dev_info(dev, "dai register i %d fail, ret
> > %d\n",
> > +				 i, ret);
> > +			return ret;
> 
> return dev_err_probe()
> 
> > +		}
> > +	}
> > +
> > +	dev_info(dev, "%s(), mtk_afe_combine_sub_dai\n", __func__);
> 
> drop this.
> 
> > +
> > +	/* init dai_driver and component_driver */
> > +	ret = mtk_afe_combine_sub_dai(afe);
> > +	if (ret) {
> > +		dev_info(dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
> > +			 ret);
> > +		return ret;
> 
> return dev_err_probe()
> 
> > +	}
> > +
> > +	/* reset controller to reset audio regs before regmap cache */
> > +	rstc = devm_reset_control_get_exclusive(dev, "audiosys");
> > +	if (IS_ERR(rstc)) {
> > +		ret = PTR_ERR(rstc);
> > +		dev_info(dev, "could not get audiosys reset:%d\n",
> > ret);
> > +		return ret;
> 
> return dev_err_probe(dev, PTR_ERR(rstc), "Could not get audiosys
> reset\n");
> 
> > +	}
> > +
> > +	ret = reset_control_reset(rstc);
> > +	if (ret) {
> > +		dev_info(dev, "failed to trigger audio reset:%d\n",
> > ret);
> > +		return ret;
> 
> dev_err_probe()
> 
> > +	}
> > +
> > +	/* enable clock for regcache get default value from hw */
> > +	afe_priv->pm_runtime_bypass_reg_ctl = true;
> > +	pm_runtime_enable(dev);
> > +	ret = pm_runtime_get_sync(dev);
> > +	if (ret)
> > +		dev_info(dev, "get_ret:%d, rpm_error:%d\n",
> > +			 ret, dev->power.runtime_error);
> 
> You should also return the error here.
> 
> > +
> > +	afe->regmap = devm_regmap_init_mmio(dev, afe->base_addr,
> > +					    &mt8186_afe_regmap_config);
> > +	if (IS_ERR(afe->regmap)) {
> > +		ret = PTR_ERR(afe->regmap);
> > +		goto err_pm_disable;
> > +	}
> > +
> > +	/* others */
> > +	afe->mtk_afe_hardware = &mt8186_afe_hardware;
> > +	afe->memif_fs = mt8186_memif_fs;
> > +	afe->irq_fs = mt8186_irq_fs;
> > +	afe->get_dai_fs = mt8186_get_dai_fs;
> > +	afe->get_memif_pbuf_size = mt8186_get_memif_pbuf_size;
> > +
> > +	afe->runtime_resume = mt8186_afe_runtime_resume;
> > +	afe->runtime_suspend = mt8186_afe_runtime_suspend;
> > +
> > +	/* register platform */
> > +	dev_info(dev, "%s(), devm_snd_soc_register_component\n",
> > __func__);
> > +
> > +	ret = devm_snd_soc_register_component(dev,
> > +					      &mt8186_afe_component,
> > +					      afe->dai_drivers,
> > +					      afe->num_dai_drivers);
> > +	if (ret) {
> > +		dev_info(dev, "err_dai_component\n");
> 
> dev_err()
> 
> > +		goto err_pm_disable;
> > +	}
> > +
> > +	ret = pm_runtime_put_sync(dev);
> > +	if (ret)
> > +		dev_info(dev, "put_ret:%d, rpm_error:%d\n",
> > +			 ret, dev->power.runtime_error);
> 
> dev_err()
> 
> > +	afe_priv->pm_runtime_bypass_reg_ctl = false;
> > +
> > +	regcache_cache_only(afe->regmap, true);
> > +	regcache_mark_dirty(afe->regmap);
> > +
> > +	dev_info(dev, "%s(), --\n", __func__);
> > +
> > +	return 0;
> > +
> > +err_pm_disable:
> > +	pm_runtime_put_sync(dev);
> > +	pm_runtime_disable(dev);
> > +
> > +	return ret;
> > +}
> > +
> > +static int mt8186_afe_pcm_dev_remove(struct platform_device *pdev)
> > +{
> > +	struct mtk_base_afe *afe = platform_get_drvdata(pdev);
> > +
> > +	pm_runtime_disable(&pdev->dev);
> > +	if (!pm_runtime_status_suspended(&pdev->dev))
> > +		mt8186_afe_runtime_suspend(&pdev->dev);
> > +
> > +	mt8186_deinit_clock(afe);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct of_device_id mt8186_afe_pcm_dt_match[] = {
> > +	{ .compatible = "mediatek,mt8186-sound", },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, mt8186_afe_pcm_dt_match);
> > +
> > +static const struct dev_pm_ops mt8186_afe_pm_ops = {
> > +	SET_RUNTIME_PM_OPS(mt8186_afe_runtime_suspend,
> > +			   mt8186_afe_runtime_resume, NULL)
> > +};
> > +
> > +static struct platform_driver mt8186_afe_pcm_driver = {
> > +	.driver = {
> > +		   .name = "mt8186-audio",
> > +		   .of_match_table = mt8186_afe_pcm_dt_match,
> > +		   .pm = &mt8186_afe_pm_ops,
> > +	},
> > +	.probe = mt8186_afe_pcm_dev_probe,
> > +	.remove = mt8186_afe_pcm_dev_remove,
> > +};
> > +
> > +module_platform_driver(mt8186_afe_pcm_driver);
> > +
> > +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for
> > 8186");
> > +MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
> > +MODULE_LICENSE("GPL v2");
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-interconnection.h
> > b/sound/soc/mediatek/mt8186/mt8186-interconnection.h
> > new file mode 100644
> > index 000000000000..5b188d93ebd3
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-interconnection.h
> > @@ -0,0 +1,69 @@
> > +/* SPDX-License-Identifier: GPL-2.0
> > + *
> > + * Mediatek MT8186 audio driver interconnection definition
> > + *
> > + * Copyright (c) 2022 MediaTek Inc.
> > + * Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > + */
> > +
> > +#ifndef _MT8186_INTERCONNECTION_H_
> > +#define _MT8186_INTERCONNECTION_H_
> > +
> > +/* in port define */
> > +#define I_I2S0_CH1 0
> > +#define I_I2S0_CH2 1
> > +#define I_ADDA_UL_CH1 3
> > +#define I_ADDA_UL_CH2 4
> > +#define I_DL1_CH1 5
> > +#define I_DL1_CH2 6
> > +#define I_DL2_CH1 7
> > +#define I_DL2_CH2 8
> > +#define I_PCM_1_CAP_CH1 9
> > +#define I_GAIN1_OUT_CH1 10
> > +#define I_GAIN1_OUT_CH2 11
> > +#define I_GAIN2_OUT_CH1 12
> > +#define I_GAIN2_OUT_CH2 13
> > +#define I_PCM_2_CAP_CH1 14
> > +#define I_ADDA_UL_CH3 17
> > +#define I_ADDA_UL_CH4 18
> > +#define I_DL12_CH1 19
> > +#define I_DL12_CH2 20
> > +#define I_DL12_CH3 5
> > +#define I_DL12_CH4 6
> > +#define I_PCM_2_CAP_CH2 21
> > +#define I_PCM_1_CAP_CH2 22
> > +#define I_DL3_CH1 23
> > +#define I_DL3_CH2 24
> > +#define I_I2S2_CH1 25
> > +#define I_I2S2_CH2 26
> > +#define I_I2S2_CH3 27
> > +#define I_I2S2_CH4 28
> > +
> > +/* in port define >= 32 */
> > +#define I_32_OFFSET 32
> > +#define I_CONNSYS_I2S_CH1 (34 - I_32_OFFSET)
> > +#define I_CONNSYS_I2S_CH2 (35 - I_32_OFFSET)
> > +#define I_SRC_1_OUT_CH1 (36 - I_32_OFFSET)
> > +#define I_SRC_1_OUT_CH2 (37 - I_32_OFFSET)
> > +#define I_SRC_2_OUT_CH1 (38 - I_32_OFFSET)
> > +#define I_SRC_2_OUT_CH2 (39 - I_32_OFFSET)
> > +#define I_DL4_CH1 (40 - I_32_OFFSET)
> > +#define I_DL4_CH2 (41 - I_32_OFFSET)
> > +#define I_DL5_CH1 (42 - I_32_OFFSET)
> > +#define I_DL5_CH2 (43 - I_32_OFFSET)
> > +#define I_DL6_CH1 (44 - I_32_OFFSET)
> > +#define I_DL6_CH2 (45 - I_32_OFFSET)
> > +#define I_DL7_CH1 (46 - I_32_OFFSET)
> > +#define I_DL7_CH2 (47 - I_32_OFFSET)
> > +#define I_DL8_CH1 (48 - I_32_OFFSET)
> > +#define I_DL8_CH2 (49 - I_32_OFFSET)
> > +#define I_TDM_IN_CH1 (56 - I_32_OFFSET)
> > +#define I_TDM_IN_CH2 (57 - I_32_OFFSET)
> > +#define I_TDM_IN_CH3 (58 - I_32_OFFSET)
> > +#define I_TDM_IN_CH4 (59 - I_32_OFFSET)
> > +#define I_TDM_IN_CH5 (60 - I_32_OFFSET)
> > +#define I_TDM_IN_CH6 (61 - I_32_OFFSET)
> > +#define I_TDM_IN_CH7 (62 - I_32_OFFSET)
> > +#define I_TDM_IN_CH8 (63 - I_32_OFFSET)
> > +
> > +#endif
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-misc-control.c
> > b/sound/soc/mediatek/mt8186/mt8186-misc-control.c
> > new file mode 100644
> > index 000000000000..c097248b37b6
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-misc-control.c
> > @@ -0,0 +1,1728 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio Misc Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/delay.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/io.h>
> > +#include <linux/regmap.h>
> > +#include <sound/soc.h>
> > +
> > +#include "../common/mtk-afe-fe-dai.h"
> > +#include "../common/mtk-afe-platform-driver.h"
> > +#include "mt8186-afe-common.h"
> > +
> > +#define SGEN_MUTE_CH1_KCONTROL_NAME "Audio_SineGen_Mute_Ch1"
> > +#define SGEN_MUTE_CH2_KCONTROL_NAME "Audio_SineGen_Mute_Ch2"
> > +
> > +static const char * const mt8186_sgen_mode_str[] = {
> > +	"I0I1",   "I2",     "I3I4",   "I5I6",
> > +	"I7I8",   "I9I22",  "I10I11", "I12I13",
> > +	"I14I21", "I15I16", "I17I18", "I19I20",
> > +	"I23I24", "I25I26", "I27I28", "I33",
> > +	"I34I35", "I36I37", "I38I39", "I40I41",
> > +	"I42I43", "I44I45", "I46I47", "I48I49",
> > +	"I56I57", "I58I59", "I60I61", "I62I63",
> > +	"O0O1",   "O2",     "O3O4",   "O5O6",
> > +	"O7O8",   "O9O10",  "O11",    "O12",
> > +	"O13O14", "O15O16", "O17O18", "O19O20",
> > +	"O21O22", "O23O24", "O25",    "O28O29",
> > +	"O34",    "O35",    "O32O33", "O36O37",
> > +	"O38O39", "O30O31", "O40O41", "O42O43",
> > +	"O44O45", "O46O47", "O48O49", "O50O51",
> > +	"O58O59", "O60O61", "O62O63", "O64O65",
> > +	"O66O67", "O68O69", "O26O27", "OFF",
> > +};
> > +
> > +static const int mt8186_sgen_mode_idx[] = {
> > +	0, 2, 4, 6,
> > +	8, 22, 10, 12,
> > +	14, -1, 18, 20,
> > +	24, 26, 28, 33,
> > +	34, 36, 38, 40,
> > +	42, 44, 46, 48,
> > +	56, 58, 60, 62,
> > +	128, 130, 132, 134,
> > +	135, 138, 139, 140,
> > +	142, 144, 166, 148,
> > +	150, 152, 153, 156,
> > +	162, 163, 160, 164,
> > +	166, -1, 168, 170,
> > +	172, 174, 176, 178,
> > +	186, 188, 190, 192,
> > +	194, 196, -1, -1,
> > +};
> > +
> > +static const char * const mt8186_sgen_rate_str[] = {
> > +	"8K", "11K", "12K", "16K",
> > +	"22K", "24K", "32K", "44K",
> > +	"48K", "88k", "96k", "176k",
> > +	"192k"
> > +};
> > +
> > +static const int mt8186_sgen_rate_idx[] = {
> > +	0, 1, 2, 4,
> > +	5, 6, 8, 9,
> > +	10, 11, 12, 13,
> > +	14
> > +};
> > +
> > +/* this order must match reg bit amp_div_ch1/2 */
> > +static const char * const mt8186_sgen_amp_str[] = {
> > +	"1/128", "1/64", "1/32", "1/16", "1/8", "1/4", "1/2", "1" };
> > +static const char * const mt8186_sgen_mute_str[] = {
> > +	"Off", "On"
> > +};
> > +
> > +static int mt8186_sgen_get(struct snd_kcontrol *kcontrol,
> > +			   struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	ucontrol->value.integer.value[0] = afe_priv->sgen_mode;
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_set(struct snd_kcontrol *kcontrol,
> > +			   struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct soc_enum *e = (struct soc_enum *)kcontrol-
> > >private_value;
> > +	int mode;
> > +	int mode_idx;
> > +
> > +	if (ucontrol->value.enumerated.item[0] >= e->items)
> > +		return -EINVAL;
> > +
> > +	mode = ucontrol->value.integer.value[0];
> > +	mode_idx = mt8186_sgen_mode_idx[mode];
> > +
> > +	dev_info(afe->dev, "%s(), mode %d, mode_idx %d\n",
> > +		 __func__, mode, mode_idx);
> > +
> > +	if (mode_idx >= 0) {
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> > +				   INNER_LOOP_BACK_MODE_MASK_SFT,
> > +				   mode_idx <<
> > INNER_LOOP_BACK_MODE_SFT);
> > +		//regmap_write(afe->regmap, AFE_SINEGEN_CON0,
> > 0x04ac2ac1);
> 
> Why is this commented out?
> Either remove the comment, or remove the line entirely.
> 
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +				   DAC_EN_MASK_SFT,
> > +				   0x1 << DAC_EN_SFT);
> 
> BIT()
> 
> > +	} else {
> > +		/* disable sgen */
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +				   DAC_EN_MASK_SFT,
> > +				   0x0);
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON2,
> > +				   INNER_LOOP_BACK_MODE_MASK_SFT,
> > +				   0x3f << INNER_LOOP_BACK_MODE_SFT);
> > +	}
> > +
> > +	afe_priv->sgen_mode = mode;
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_rate_get(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	ucontrol->value.integer.value[0] = afe_priv->sgen_rate;
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_rate_set(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct soc_enum *e = (struct soc_enum *)kcontrol-
> > >private_value;
> > +	int rate;
> > +
> > +	if (ucontrol->value.enumerated.item[0] >= e->items)
> > +		return -EINVAL;
> > +
> > +	rate = ucontrol->value.integer.value[0];
> > +
> > +	dev_info(afe->dev, "%s(), rate %d\n", __func__, rate);
> 
> dev_dbg()
> 
> > +
> > +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +			   SINE_MODE_CH1_MASK_SFT,
> > +			   mt8186_sgen_rate_idx[rate] <<
> > SINE_MODE_CH1_SFT);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +			   SINE_MODE_CH2_MASK_SFT,
> > +			   mt8186_sgen_rate_idx[rate] <<
> > SINE_MODE_CH2_SFT);
> > +
> > +	afe_priv->sgen_rate = rate;
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_amplitude_get(struct snd_kcontrol
> > *kcontrol,
> > +				     struct snd_ctl_elem_value
> > *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +
> > +	ucontrol->value.integer.value[0] = afe_priv->sgen_amplitude;
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_amplitude_set(struct snd_kcontrol
> > *kcontrol,
> > +				     struct snd_ctl_elem_value
> > *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct soc_enum *e = (struct soc_enum *)kcontrol-
> > >private_value;
> > +	int amplitude;
> > +
> > +	if (ucontrol->value.enumerated.item[0] >= e->items)
> > +		return -EINVAL;
> > +
> > +	amplitude = ucontrol->value.integer.value[0];
> > +	if (amplitude > AMP_DIV_CH1_MASK) {
> > +		dev_info(afe->dev, "%s(), amplitude %d invalid\n",
> > +			 __func__, amplitude);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	dev_info(afe->dev, "%s(), amplitude %d\n", __func__,
> > amplitude);
> > +
> > +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +			   AMP_DIV_CH1_MASK_SFT,
> > +			   amplitude << AMP_DIV_CH1_SFT);
> > +	regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +			   AMP_DIV_CH2_MASK_SFT,
> > +			   amplitude << AMP_DIV_CH2_SFT);
> > +
> > +	afe_priv->sgen_amplitude = amplitude;
> > +
> > +	return 0;
> > +}
> > +
> > +static int mt8186_sgen_mute_get(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	int mute;
> > +
> > +	regmap_read(afe->regmap, AFE_SINEGEN_CON0, &mute);
> > +
> > +	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) ==
> > 0)
> > +		return (mute >> MUTE_SW_CH1_SFT) & MUTE_SW_CH1_MASK;
> > +	else
> > +		return (mute >> MUTE_SW_CH2_SFT) & MUTE_SW_CH2_MASK;
> 
> 	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) ==
> 0)
> 		return (mute >> MUTE_SW_CH1_SFT) & MUTE_SW_CH1_MASK;
> 
> 	return (mute >> MUTE_SW_CH2_SFT) & MUTE_SW_CH2_MASK;
> 
> > +}
> > +
> > +static int mt8186_sgen_mute_set(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct soc_enum *e = (struct soc_enum *)kcontrol-
> > >private_value;
> > +	int mute;
> > +
> > +	if (ucontrol->value.enumerated.item[0] >= e->items)
> > +		return -EINVAL;
> > +
> > +	mute = ucontrol->value.integer.value[0];
> > +
> > +	dev_info(afe->dev, "%s(), kcontrol name %s, mute %d\n",
> > +		 __func__, kcontrol->id.name, mute);
> 
> dev_dbg()
> 
> > +
> > +	if (strcmp(kcontrol->id.name, SGEN_MUTE_CH1_KCONTROL_NAME) ==
> > 0) {
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +				   MUTE_SW_CH1_MASK_SFT,
> > +				   mute << MUTE_SW_CH1_SFT);
> > +	} else {
> > +		regmap_update_bits(afe->regmap, AFE_SINEGEN_CON0,
> > +				   MUTE_SW_CH2_MASK_SFT,
> > +				   mute << MUTE_SW_CH2_SFT);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct soc_enum mt8186_afe_sgen_enum[] = {
> > +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mode_str),
> > +			    mt8186_sgen_mode_str),
> > +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_rate_str),
> > +			    mt8186_sgen_rate_str),
> > +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_amp_str),
> > +			    mt8186_sgen_amp_str),
> > +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_sgen_mute_str),
> > +			    mt8186_sgen_mute_str),
> > +};
> > +
> > +static const struct snd_kcontrol_new mt8186_afe_sgen_controls[] =
> > {
> > +	SOC_ENUM_EXT("Audio_SineGen_Switch", mt8186_afe_sgen_enum[0],
> > +		     mt8186_sgen_get, mt8186_sgen_set),
> > +	SOC_ENUM_EXT("Audio_SineGen_SampleRate",
> > mt8186_afe_sgen_enum[1],
> > +		     mt8186_sgen_rate_get, mt8186_sgen_rate_set),
> > +	SOC_ENUM_EXT("Audio_SineGen_Amplitude",
> > mt8186_afe_sgen_enum[2],
> > +		     mt8186_sgen_amplitude_get,
> > mt8186_sgen_amplitude_set),
> > +	SOC_ENUM_EXT(SGEN_MUTE_CH1_KCONTROL_NAME,
> > mt8186_afe_sgen_enum[3],
> > +		     mt8186_sgen_mute_get, mt8186_sgen_mute_set),
> > +	SOC_ENUM_EXT(SGEN_MUTE_CH2_KCONTROL_NAME,
> > mt8186_afe_sgen_enum[3],
> > +		     mt8186_sgen_mute_get, mt8186_sgen_mute_set),
> > +	SOC_SINGLE("Audio_SineGen_Freq_Div_Ch1", AFE_SINEGEN_CON0,
> > +		   FREQ_DIV_CH1_SFT, FREQ_DIV_CH1_MASK, 0),
> > +	SOC_SINGLE("Audio_SineGen_Freq_Div_Ch2", AFE_SINEGEN_CON0,
> > +		   FREQ_DIV_CH2_SFT, FREQ_DIV_CH2_MASK, 0),
> > +};
> > +
> > +/* audio debug log */
> > +static const char * const mt8186_afe_off_on_str[] = {
> > +	"Off", "On"
> > +};
> > +
> > +static int mt8186_afe_debug_get(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	return 0;
> > +}
> > +
> > +static int mt8186_afe_debug_set(struct snd_kcontrol *kcontrol,
> > +				struct snd_ctl_elem_value *ucontrol)
> > +{
> > +	struct snd_soc_component *cmpnt =
> > snd_soc_kcontrol_component(kcontrol);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	unsigned int value;
> > +
> 
> This should be debugfs, instead of spitting a full register dump in
> the kmsg:
> doing so is horrible (sorry).
Yes, I will remove them in next version.

> 
> > +	regmap_read(afe->regmap, AUDIO_TOP_CON0, &value);
> > +	dev_info(afe->dev, "AUDIO_TOP_CON0 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AUDIO_TOP_CON1, &value);
> > +	dev_info(afe->dev, "AUDIO_TOP_CON1 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AUDIO_TOP_CON2, &value);
> > +	dev_info(afe->dev, "AUDIO_TOP_CON2 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AUDIO_TOP_CON3, &value);
> > +	dev_info(afe->dev, "AUDIO_TOP_CON3 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AFE_DAC_CON0, &value);
> > +	dev_info(afe->dev, "AFE_DAC_CON0 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AFE_I2S_CON, &value);
> > +	dev_info(afe->dev, "AFE_I2S_CON = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AFE_CONN0, &value);
> > +	dev_info(afe->dev, "AFE_CONN0 = 0x%x\n", value);
> > 
snip ...

> > +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN54_1, &value);
> > +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN54_1 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN55_1, &value);
> > +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN55_1 = 0x%x\n", value);
> > +	regmap_read(afe->regmap, AFE_SECURE_MASK_CONN56_1, &value);
> > +	dev_info(afe->dev, "AFE_SECURE_MASK_CONN56_1 = 0x%x\n", value);
> > +
> > +	return 0;
> > +}
> > +
> > +static const struct soc_enum mt8186_afe_misc_enum[] = {
> > +	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_afe_off_on_str),
> > +			    mt8186_afe_off_on_str),
> > +};
> > +
> > +static const struct snd_kcontrol_new mt8186_afe_debug_controls[] =
> > {
> > +	SOC_ENUM_EXT("Audio_Debug_Setting", mt8186_afe_misc_enum[0],
> > +		     mt8186_afe_debug_get, mt8186_afe_debug_set),
> > +};
> > +
> > +int mt8186_add_misc_control(struct snd_soc_component *component)
> > +{
> > +	snd_soc_add_component_controls(component,
> > +				       mt8186_afe_sgen_controls,
> > +				       ARRAY_SIZE(mt8186_afe_sgen_contr
> > ols));
> > +
> > +	snd_soc_add_component_controls(component,
> > +				       mt8186_afe_debug_controls,
> > +				       ARRAY_SIZE(mt8186_afe_debug_cont
> > rols));
> > +
> > +	return 0;
> > +}
Jiaxin Yu (俞家鑫) March 5, 2022, 10:49 a.m. UTC | #22
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch adds mt8186 adda dai driver
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 891
> > ++++++++++++++++++++
> >   1 file changed, 891 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> > b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> > new file mode 100644
> > index 000000000000..6d7dd1533da0
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
> > @@ -0,0 +1,891 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio DAI ADDA Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/regmap.h>
> > +#include <linux/delay.h>
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-gpio.h"
> > +#include "mt8186-interconnection.h"
> > +
...snip...
> > 
> > +/* dai ops */
> > +static int mtk_dai_adda_hw_params(struct snd_pcm_substream
> > *substream,
> > +				  struct snd_pcm_hw_params *params,
> > +				  struct snd_soc_dai *dai)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	unsigned int rate = params_rate(params);
> > +	int id = dai->id;
> > +	struct mtk_afe_adda_priv *adda_priv = afe_priv->dai_priv[id];
> > +
> > +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> > +		 __func__,
> > +		 id,
> > +		 substream->stream,
> > +		 rate);
> > +
> > +	if (!adda_priv) {
> > +		dev_info(afe->dev, "%s(), adda_priv == NULL",
> > __func__);
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> > +		unsigned int dl_src2_con0 = 0;
> > +		unsigned int dl_src2_con1 = 0;
> 
> This initialization is redundant: you're never using these variables
> before initializing them later, so initializing them to zero is not
> needed here.
Yes, got it. Thank you.
> 
> > +
> > +		adda_priv->dl_rate = rate;
> > +
> > +		/* set sampling rate */
> > +		dl_src2_con0 = adda_dl_rate_transform(afe, rate) <<
> > +			       DL_2_INPUT_MODE_CTL_SFT;
> > +
> > +		/* set output mode, UP_SAMPLING_RATE_X8 */
> > +		dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT);
> > +
> > +		/* turn off mute function */
> > +		dl_src2_con0 |= (0x01 <<
> > DL_2_MUTE_CH2_OFF_CTL_PRE_SFT);
> 
> BIT() macro, please
> 
> > +		dl_src2_con0 |= (0x01 <<
> > DL_2_MUTE_CH1_OFF_CTL_PRE_SFT);
> > +
> > +		/* set voice input data if input sample rate is 8k or
> > 16k */
> > +		if (rate == 8000 || rate == 16000)
> > +			dl_src2_con0 |= 0x01 <<
> > DL_2_VOICE_MODE_CTL_PRE_SFT;
> > +
> > +		/* SA suggest apply -0.3db to audio/speech path */
> > +		dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL <<
> > +			       DL_2_GAIN_CTL_PRE_SFT;
> > +
> > +		/* turn on down-link gain */
> > +		dl_src2_con0 |= (0x01 << DL_2_GAIN_ON_CTL_PRE_SFT);
> > +
> > +		if (id == MT8186_DAI_ADDA) {
> > +			/* clean predistortion */
> > +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0,
> > 0);
> > +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1,
> > 0);
> > +
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_DL_SRC2_CON0,
> > dl_src2_con0);
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_DL_SRC2_CON1,
> > dl_src2_con1);
> > +
> > +			/* set sdm gain */
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
> > +					   ATTGAIN_CTL_MASK_SFT,
> > +					   AUDIO_SDM_LEVEL_NORMAL <<
> > +					   ATTGAIN_CTL_SFT);
> > +
> > +			/* Use new 2nd sdm */
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_DL_SDM_DITHER_CON,
> > +					   AFE_DL_SDM_DITHER_64TAP_EN_M
> > ASK_SFT,
> > +					   0x1 <<
> > AFE_DL_SDM_DITHER_64TAP_EN_SFT);
> 
> BIT(AFE_DL_SDM_DITHER_64TAP_EN_SFT)
> 
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_DL_SDM_AUTO_RESET_C
> > ON,
> > +					   AFE_DL_USE_NEW_2ND_SDM_MASK_
> > SFT,
> > +					   0x1 <<
> > AFE_DL_USE_NEW_2ND_SDM_SFT);
> 
> BIT(AFE_DL_USE_NEW_2ND_SDM_SFT)
> 
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
> > +					   USE_3RD_SDM_MASK_SFT,
> > +					   AUDIO_SDM_2ND <<
> > USE_3RD_SDM_SFT);
> > +
> > +			/* sdm auto reset */
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_DL_SDM_AUTO_RESET_CON,
> > +				     SDM_AUTO_RESET_THRESHOLD);
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_DL_SDM_AUTO_RESET_C
> > ON,
> > +					   SDM_AUTO_RESET_TEST_ON_MASK_
> > SFT,
> > +					   0x1 <<
> > SDM_AUTO_RESET_TEST_ON_SFT);
> 
> BIT(SDM_AUTO_RESET_TEST_ON_SFT)
> 
> > +		}
> > +	} else {
> > +		unsigned int voice_mode = 0;
> 
> what about...
> 		unsigned int ul_src_con0 = 0; /* default value */
> 		unsigned int voice_mode =  adda_ul_rate_transform(afe,
> rate);
Agree with you.

> > +		unsigned int ul_src_con0 = 0;	/* default value */
> > +
> > +		adda_priv->ul_rate = rate;
> > +
> > +		voice_mode = adda_ul_rate_transform(afe, rate);
> > +
> > +		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
> > +
> > +		/* enable iir */
> > +		ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) &
> > +			       UL_IIR_ON_TMP_CTL_MASK_SFT;
> > +		ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) &
> > +			       UL_IIRMODE_CTL_MASK_SFT;
> > +		switch (id) {
> > +		case MT8186_DAI_ADDA:
> > +		case MT8186_DAI_AP_DMIC:
> > +			/* 35Hz @ 48k */
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_IIR_COEF_02_01,
> > 0x00000000);
> 
> Please drop leading zeroes:
> 
> regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_02_01, 0);
> 
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_IIR_COEF_04_03,
> > 0x00003FB8);
> 
> ... and also please write hex in lower-case:
> 
Got it.
> regmap_write(afe->regmap,
> 	     AFE_ADDA_IIR_COEF_04_03, 0x03fb8);
> 
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_IIR_COEF_06_05,
> > 0x3FB80000);
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_IIR_COEF_08_07,
> > 0x3FB80000);
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_IIR_COEF_10_09,
> > 0x0000C048);
> > +
> > +			regmap_write(afe->regmap,
> > +				     AFE_ADDA_UL_SRC_CON0,
> > ul_src_con0);
> > +
> > +			/* Using Internal ADC */
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_TOP_CON0,
> > +					   0x1 << 0,
> > +					   0x0 << 0);
> 
> Please use the BIT() macro:
> 
> regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, BIT(0), 0);
> 
> P.S.: 87 columns is ok

How can I judge whether it can exceed 80 lines?
> 
> > +
> > +			/* mtkaif_rxif_data_mode = 0, amic */
> > +			regmap_update_bits(afe->regmap,
> > +					   AFE_ADDA_MTKAIF_RX_CFG0,
> > +					   0x1 << 0,
> > +					   0x0 << 0);
> 
> same here.
> 
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +
> > +		/* ap dmic */
> > +		switch (id) {
> > +		case MT8186_DAI_AP_DMIC:
> > +			mtk_adda_ul_src_dmic(afe, id);
> > +			break;
> > +		default:
> > +			break;
> > +		}
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> Regards,
> Angelo
>
Jiaxin Yu (俞家鑫) March 5, 2022, 11:07 a.m. UTC | #23
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch adds mt8186 i2s dai driver
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-dai-i2s.c | 1371
> > ++++++++++++++++++++
> >   1 file changed, 1371 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> > b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> > new file mode 100644
> > index 000000000000..d6db5f6a7315
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
> > @@ -0,0 +1,1371 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio DAI I2S Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/bitops.h>
> > +#include <linux/regmap.h>
> > +#include <sound/pcm_params.h>
> > +#include "mt8186-afe-clk.h"
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-gpio.h"
> > +#include "mt8186-interconnection.h"
> > +
> > 
> > +static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget
> > *source,
> > +				     struct snd_soc_dapm_widget *sink)
> > +{
> > +	struct snd_soc_dapm_widget *w = sink;
> > +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mtk_afe_i2s_priv *i2s_priv;
> > +
> > +	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
> > +
> > +	if (!i2s_priv) {
> > +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);
> 
> Is this an error? => dev_err()
> Is this expected? => dev_dbg()
> 
It should be an error here and use dev_err().
I will fix the rest of the similar log level issues.

> > +		return 0;
> > +	}
> > +
> > +	if (i2s_priv->share_i2s_id < 0)
> > +		return 0;
> > +
> > +	return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe,
> > source->name);
> > +}
> > +
> > +static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget
> > *source,
> > +				  struct snd_soc_dapm_widget *sink)
> > +{
> > +	struct snd_soc_dapm_widget *w = sink;
> > +	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > +	struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +	struct mtk_afe_i2s_priv *i2s_priv;
> > +
> > +	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
> > +
> > +	if (!i2s_priv) {
> > +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);
> 
> Is this an error? => dev_err()
> Is this expected? => dev_dbg()
> 
> Please fix all of the other instances of this.
> 
Yes, I know.

> > +		return 0;
> > +	}
> > +
> > +	if (get_i2s_id_by_name(afe, sink->name) ==
> > +	    get_i2s_id_by_name(afe, source->name))
> > +		return i2s_priv->low_jitter_en;
> > +
> > +	/* check if share i2s need hd en */
> > +	if (i2s_priv->share_i2s_id < 0)
> > +		return 0;
> > +
> > +	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source-
> > >name))
> > +		return i2s_priv->low_jitter_en;
> > +
> > +	return 0;
> > +}
> > +
> 
> ..snip...
> 
> > +
> > +/* dai ops */
> > +static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream
> > *substream,
> > +					 struct snd_pcm_hw_params
> > *params,
> > +					 struct snd_soc_dai *dai)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	unsigned int rate = params_rate(params);
> > +	unsigned int rate_reg = mt8186_rate_transform(afe->dev,
> > +						      rate, dai->id);
> > +	unsigned int i2s_con = 0;
> > +
> > +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
> > +		 __func__,
> > +		 dai->id,
> > +		 substream->stream,
> > +		 rate);
> > +
> > +	/* non-inverse, i2s mode, slave, 16bits, from connsys */
> > +	i2s_con |= 0 << INV_PAD_CTRL_SFT;
> > +	i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
> > +	i2s_con |= 1 << I2S_SRC_SFT;
> > +	i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) <<
> > I2S_WLEN_SFT;
> > +	i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
> > +	regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
> > +
> > +	/* use asrc */
> > +	regmap_update_bits(afe->regmap,
> > +			   AFE_CONNSYS_I2S_CON,
> > +			   I2S_BYPSRC_MASK_SFT,
> > +			   0x0 << I2S_BYPSRC_SFT);
> 
> Zero shifted of a billion bits is still zero.
> 
Got it.

> regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
> I2S_BYPSRC_MASK_SFT, 0);
> 
> > +
> > +	/* slave mode, set i2s for asrc */
> > +	regmap_update_bits(afe->regmap,
> > +			   AFE_CONNSYS_I2S_CON,
> > +			   I2S_MODE_MASK_SFT,
> > +			   rate_reg << I2S_MODE_SFT);
> 
> 	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
> 
> 			   I2S_MODE_MASK_SFT, rate_reg <<
> I2S_MODE_SFT);
> 
> > +
> > +	if (rate == 44100)
> > +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3,
> > 0x001B9000);
> 
> lower case hex, please, and no leading zeros.
> 
Got it.
> > +	else if (rate == 32000)
> > +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
> > +	else
> > +		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3,
> > 0x001E0000);
> > +
> > +	/* Calibration setting */
> > +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x00140000);
> > +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x00036000);
> > +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x0002FC00);
> > +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x00007EF4);
> > +	regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0x00FF5986);
> 

snip...
> > +
> > +	if (i2s_priv)
> > +		i2s_priv->rate = rate;
> > +	else
> > +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);
> 
> I'm not sure about this print, maybe this should also be dev_dbg()
> 
It should be return error.
> > +
> > +	switch (i2s_id) {
> > +	case MT8186_DAI_I2S_0:
> > +		i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
> > +		i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
> > +		i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
> > +		i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
> > +		regmap_update_bits(afe->regmap, AFE_I2S_CON,
> > +				   0xffffeffa, i2s_con);
> > +		break;
> > +	case MT8186_DAI_I2S_1:
> > +		i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
> > +		i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
> > +		i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
> > +		i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
> > +		regmap_update_bits(afe->regmap, AFE_I2S_CON1,
> > +				   0xffffeffa, i2s_con);
> > +		break;
> > +	case MT8186_DAI_I2S_2:
> > +		i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
> > +		i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
> > +		i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
> > +		i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
> > +		regmap_update_bits(afe->regmap, AFE_I2S_CON2,
> > +				   0xffffeffa, i2s_con);
> > +		break;
> > +	case MT8186_DAI_I2S_3:
> > +		i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
> > +		i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
> > +		i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
> > +		regmap_update_bits(afe->regmap, AFE_I2S_CON3,
> > +				   0xffffeffa, i2s_con);
> > +		break;
> > +	default:
> > +		dev_info(afe->dev, "%s(), id %d not support\n",
> > +			 __func__, i2s_id);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* set share i2s */
> > +	if (i2s_priv && i2s_priv->share_i2s_id >= 0)
> > +		ret = mtk_dai_i2s_config(afe, params, i2s_priv-
> > >share_i2s_id);
> > +
> 
> 	if (i2s_priv && i2s_priv->share_i2s_id >= 0) {
> 
> 		ret = mtk_dai_i2s_config(afe, params, i2s_priv-
> >share_i2s_id);
> 
> 		if (ret)
> 
> 			return ret;
> 
> 	}
> 
> 
> 
> 	return 0;
> 
> > +	return ret;
> > +}
> > +
> > +static int mtk_dai_i2s_hw_params(struct snd_pcm_substream
> > *substream,
> > +				 struct snd_pcm_hw_params *params,
> > +				 struct snd_soc_dai *dai)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +
> > +	return mtk_dai_i2s_config(afe, params, dai->id);
> > +}
> > +
> > +static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
> > +				  int clk_id, unsigned int freq, int
> > dir)
> > +{
> > +	struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai-
> > >id];
> > +	int apll;
> > +	int apll_rate;
> > +
> > +	if (!i2s_priv) {
> > +		dev_info(afe->dev, "%s(), i2s_priv == NULL", __func__);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (dir != SND_SOC_CLOCK_OUT) {
> > +		dev_info(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT",
> > __func__);
> 
> again...
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	dev_info(afe->dev, "%s(), freq %d\n", __func__, freq);
> 
> dev_dbg()
> 
> > +
> > +	apll = mt8186_get_apll_by_rate(afe, freq);
> > +	apll_rate = mt8186_get_apll_rate(afe, apll);
> > +
> > +	if (freq > apll_rate) {
> > +		dev_info(afe->dev, "%s(), freq > apll rate", __func__);
> 
> dev_err() .... please fix the rest as well.
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (apll_rate % freq != 0) {
> > +		dev_info(afe->dev, "%s(), APLL cannot generate freq
> > Hz", __func__);
> > +		return -EINVAL;
> > +	}
> > +
> > +	i2s_priv->mclk_rate = freq;
> > +	i2s_priv->mclk_apll = apll;
> > +
> > +	if (i2s_priv->share_i2s_id > 0) {
> > +		struct mtk_afe_i2s_priv *share_i2s_priv;
> > +
> > +		share_i2s_priv = afe_priv->dai_priv[i2s_priv-
> > >share_i2s_id];
> > +		if (!share_i2s_priv) {
> > +			dev_info(afe->dev, "%s(), share_i2s_priv ==
> > NULL", __func__);
> > +			return -EINVAL;
> > +		}
> > +
> > +		share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
> > +		share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> 
> Regards,
> Angelo
>
Jiaxin Yu (俞家鑫) March 5, 2022, 11:12 a.m. UTC | #24
On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
> > This patch adds mt8186 pcm dai driver.
> > 
> > Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > ---
> >   sound/soc/mediatek/mt8186/mt8186-dai-pcm.c | 432
> > +++++++++++++++++++++
> >   1 file changed, 432 insertions(+)
> >   create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> > 
> > diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> > b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> > new file mode 100644
> > index 000000000000..73b3f720ed35
> > --- /dev/null
> > +++ b/sound/soc/mediatek/mt8186/mt8186-dai-pcm.c
> > @@ -0,0 +1,432 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +//
> > +// MediaTek ALSA SoC Audio DAI I2S Control
> > +//
> > +// Copyright (c) 2022 MediaTek Inc.
> > +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
> > +
> > +#include <linux/regmap.h>
> > +#include <sound/pcm_params.h>
> > +#include "mt8186-afe-common.h"
> > +#include "mt8186-afe-gpio.h"
> > +#include "mt8186-interconnection.h"
> > +
> > +struct mtk_afe_pcm_priv {
> > +	unsigned int id;
> > +	unsigned int fmt;
> > +	unsigned int bck_invert;
> > +	unsigned int lck_invert;
> > +};
> > +
> > +enum AUD_TX_LCH_RPT {
> 
> lowercase enumeration names please...
> 
> enum aud_tx_lch_rpt {
> 	AUD_TX....BLAH
> };
> 
Ok, I will fix them.

> > +	AUD_TX_LCH_RPT_NO_REPEAT = 0,
> > +	AUD_TX_LCH_RPT_REPEAT = 1
> > +};
> > +
> > +enum AUD_VBT_16K_MODE {
> > +	AUD_VBT_16K_MODE_DISABLE = 0,
> > +	AUD_VBT_16K_MODE_ENABLE = 1
> > +};
> > +
> > +enum AUD_EXT_MODEM {
> > +	AUD_EXT_MODEM_SELECT_INTERNAL = 0,
> > +	AUD_EXT_MODEM_SELECT_EXTERNAL = 1
> > +};
> > +
> > +enum AUD_PCM_SYNC_TYPE {
> > +	/* bck sync length = 1 */
> > +	AUD_PCM_ONE_BCK_CYCLE_SYNC = 0,
> > +	/* bck sync length = PCM_INTF_CON1[9:13] */
> > +	AUD_PCM_EXTENDED_BCK_CYCLE_SYNC = 1
> > +};
> > +
> > +enum AUD_BT_MODE {
> > +	AUD_BT_MODE_DUAL_MIC_ON_TX = 0,
> > +	AUD_BT_MODE_SINGLE_MIC_ON_TX = 1
> > +};
> > +
> > +enum AUD_PCM_AFIFO_SRC {
> > +	/* slave mode & external modem uses different crystal */
> > +	AUD_PCM_AFIFO_ASRC = 0,
> > +	/* slave mode & external modem uses the same crystal */
> > +	AUD_PCM_AFIFO_AFIFO = 1
> > +};
> > +
> > +enum AUD_PCM_CLOCK_SOURCE {
> > +	AUD_PCM_CLOCK_MASTER_MODE = 0,
> > +	AUD_PCM_CLOCK_SLAVE_MODE = 1
> > +};
> > +
> > +enum AUD_PCM_WLEN {
> > +	AUD_PCM_WLEN_PCM_32_BCK_CYCLES = 0,
> > +	AUD_PCM_WLEN_PCM_64_BCK_CYCLES = 1
> > +};
> > +
> > +enum AUD_PCM_24BIT {
> > +	AUD_PCM_24BIT_PCM_16_BITS = 0,
> > +	AUD_PCM_24BIT_PCM_24_BITS = 1
> > +};
> > +
> > +enum AUD_PCM_MODE {
> > +	AUD_PCM_MODE_PCM_MODE_8K = 0,
> > +	AUD_PCM_MODE_PCM_MODE_16K = 1,
> > +	AUD_PCM_MODE_PCM_MODE_32K = 2,
> > +	AUD_PCM_MODE_PCM_MODE_48K = 3,
> > +};
> > +
> > +enum AUD_PCM_FMT {
> > +	AUD_PCM_FMT_I2S = 0,
> > +	AUD_PCM_FMT_EIAJ = 1,
> > +	AUD_PCM_FMT_PCM_MODE_A = 2,
> > +	AUD_PCM_FMT_PCM_MODE_B = 3
> > +};
> > +
> > +enum AUD_BCLK_OUT_INV {
> > +	AUD_BCLK_OUT_INV_NO_INVERSE = 0,
> > +	AUD_BCLK_OUT_INV_INVERSE = 1
> > +};
> > +
> > +enum AUD_LRCLK_OUT_INV {
> > +	AUD_LRCLK_OUT_INV_NO_INVERSE = 0,
> > +	AUD_LRCLK_OUT_INV_INVERSE = 1
> > +};
> > +
> > +enum AUD_PCM_EN {
> > +	AUD_PCM_EN_DISABLE = 0,
> > +	AUD_PCM_EN_ENABLE = 1
> > +};
> > +
> 
> ..snip..
> 
> > +
> > +/* dai ops */
> > +static int mtk_dai_pcm_hw_params(struct snd_pcm_substream
> > *substream,
> > +				 struct snd_pcm_hw_params *params,
> > +				 struct snd_soc_dai *dai)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	int pcm_id = dai->id;
> > +	struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[pcm_id];
> > +	unsigned int rate = params_rate(params);
> > +	unsigned int rate_reg = mt8186_rate_transform(afe->dev, rate,
> > dai->id);
> > +	snd_pcm_format_t format = params_format(params);
> > +	unsigned int data_width =
> > +		snd_pcm_format_width(format);
> > +	unsigned int wlen_width =
> > +		snd_pcm_format_physical_width(format);
> > +	unsigned int pcm_con = 0;
> > +
> > +	dev_info(afe->dev, "%s(), id %d, stream %d, widget active p %d,
> > c %d\n",
> > +		 __func__,
> > +		 dai->id,
> > +		 substream->stream,
> > +		 dai->playback_widget->active,
> > +		 dai->capture_widget->active);
> > +	dev_info(afe->dev, "%s(), rate %d, rate_reg %d, data_width %d,
> > wlen_width %d\n",
> > +		 __func__,
> > +		 rate,
> > +		 rate_reg,
> > +		 data_width,
> > +		 wlen_width);
> 
> dev_dbg() - also, you don't need one line per variable.
> 

Yes, I will line them up in two.
> > +
> > +	if (dai->playback_widget->active || dai->capture_widget-
> > >active)
> > +		return 0;
> > +
> > +	switch (dai->id) {
> > +	case MT8186_DAI_PCM:
> > +		pcm_con |= AUD_TX_LCH_RPT_NO_REPEAT <<
> > PCM_TX_LCH_RPT_SFT;
> > +		pcm_con |= AUD_VBT_16K_MODE_DISABLE <<
> > PCM_VBT_16K_MODE_SFT;
> > +		pcm_con |= AUD_EXT_MODEM_SELECT_EXTERNAL <<
> > PCM_EXT_MODEM_SFT;
> > +		pcm_con |= AUD_PCM_ONE_BCK_CYCLE_SYNC <<
> > PCM_SYNC_TYPE_SFT;
> > +		pcm_con |= AUD_BT_MODE_DUAL_MIC_ON_TX <<
> > PCM_BT_MODE_SFT;
> > +		pcm_con |= AUD_PCM_AFIFO_AFIFO << PCM_BYP_ASRC_SFT;
> > +		pcm_con |= AUD_PCM_CLOCK_MASTER_MODE << PCM_SLAVE_SFT;
> > +		pcm_con |= 0 << PCM_SYNC_LENGTH_SFT;
> > +
> > +		/* sampling rate */
> > +		pcm_con |= rate_reg << PCM_MODE_SFT;
> > +
> > +		/* format */
> > +		pcm_con |= pcm_priv->fmt << PCM_FMT_SFT;
> > +
> > +		/* 24bit data width */
> > +		if (data_width > 16)
> > +			pcm_con |= AUD_PCM_24BIT_PCM_24_BITS <<
> > PCM_24BIT_SFT;
> > +		else
> > +			pcm_con |= AUD_PCM_24BIT_PCM_16_BITS <<
> > PCM_24BIT_SFT;
> > +
> > +		/* wlen width*/
> > +		if (wlen_width > 16)
> > +			pcm_con |= AUD_PCM_WLEN_PCM_64_BCK_CYCLES <<
> > PCM_WLEN_SFT;
> > +		else
> > +			pcm_con |= AUD_PCM_WLEN_PCM_32_BCK_CYCLES <<
> > PCM_WLEN_SFT;
> > +
> > +		/* clock invert */
> > +		pcm_con |= pcm_priv->lck_invert <<
> > PCM_SYNC_OUT_INV_SFT;
> > +		pcm_con |= pcm_priv->bck_invert <<
> > PCM_BCLK_OUT_INV_SFT;
> > +
> > +		regmap_update_bits(afe->regmap, PCM_INTF_CON1,
> > +				   0xfffffffe, pcm_con);
> 
> Fits in one line.
> 
> > +		break;
> > +	default:
> > +		dev_info(afe->dev, "%s(), id %d not support\n",
> > +			 __func__, dai->id);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned
> > int fmt)
> > +{
> > +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
> > +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
> > +	struct mtk_afe_pcm_priv *pcm_priv = afe_priv->dai_priv[dai-
> > >id];
> > +
> > +	if (!pcm_priv) {
> > +		dev_info(afe->dev, "%s(), tdm_priv == NULL", __func__);
> 
> dev_err()
> 
> > +		return -EINVAL;
> > +	}
> > +
AngeloGioacchino Del Regno March 7, 2022, 9:07 a.m. UTC | #25
Il 05/03/22 05:24, Jiaxin Yu ha scritto:
> On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
>> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
>>> Mt6366 is a new version of mt6358, and they are same about audio
>>> part.
>>> So we can reuse the driver of mt6358.
>>>
>>> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>
>> Hello Jiaxin,
>> I'm sorry but this commit makes very little sense.
>>
>> If you want to advertise MT6366 support, please write a note and/or
>> a new compatible string inside of the mt6358 driver (and dt-
>> bindings),
>> then, please drop this commit.
>>
> 
> Hello angelogioacchino,
> 
> Thank you for your advice.
> 
> If I add a new compatible string inside of the mt6358 driver and dt-
> bindings, then the machine driver which want to use mt6366 should
> select SND_SOC_MT6358.
> 
> like below:
> 
> config SND_SOC_MT8186_MT6366_DA7219_MAX98357
> 	tristate "ASoC Audio driver for MT8186 with DA7219 MAX98357A
> codec"
>   	depends on I2C && GPIOLIB
>   	depends on SND_SOC_MT8186 && MTK_PMIC_WRAP
>   	select SND_SOC_MT6366   ==> SND_SOC_MT6358
> 	...
> 
> I just doubt it's enough to make sense. I originally wanted to put this
> relationship in the sound/soc/codecs layer. So that this relationship
> is not perceived by users(machine driver).
> However, if the general practice is like this, I will adopt your
> suggestion. Thank you again.
> 

Yes this is acceptable, please do it like that.

Thanks,
Angelo

>>
>>> ---
>>>    sound/soc/codecs/Kconfig  | 8 ++++++++
>>>    sound/soc/codecs/Makefile | 1 +
>>>    2 files changed, 9 insertions(+)
>>>
>>> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
>>> index 8fa24783ce01..6631094678f5 100644
>>> --- a/sound/soc/codecs/Kconfig
>>> +++ b/sound/soc/codecs/Kconfig
>>> @@ -132,6 +132,7 @@ config SND_SOC_ALL_CODECS
>>>    	imply SND_SOC_MT6351
>>>    	imply SND_SOC_MT6358
>>>    	imply SND_SOC_MT6359
>>> +	imply SND_SOC_MT6366
>>>    	imply SND_SOC_MT6660
>>>    	imply SND_SOC_NAU8315
>>>    	imply SND_SOC_NAU8540
>>> @@ -1888,6 +1889,13 @@ config SND_SOC_MT6359_ACCDET
>>>    	  for ASoC codec soc-jack detection mechanism.
>>>    	  Select N if you don't have jack on board.
>>>    
>>> +config SND_SOC_MT6366
>>> +	tristate "MediaTek MT6366 Codec"
>>> +	depends on MTK_PMIC_WRAP
>>> +	help
>>> +	  Enable support for the platform which uses MT6366 as
>>> +	  external codec device.
>>> +
>>>    config SND_SOC_MT6660
>>>    	tristate "Mediatek MT6660 Speaker Amplifier"
>>>    	depends on I2C
>>> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
>>> index 42d00aa4ee46..1279684feaf0 100644
>>> --- a/sound/soc/codecs/Makefile
>>> +++ b/sound/soc/codecs/Makefile
>>> @@ -465,6 +465,7 @@ obj-$(CONFIG_SND_SOC_MT6351)	+= snd-soc-
>>> mt6351.o
>>>    obj-$(CONFIG_SND_SOC_MT6358)	+= snd-soc-mt6358.o
>>>    obj-$(CONFIG_SND_SOC_MT6359)	+= snd-soc-mt6359.o
>>>    obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o
>>> +obj-$(CONFIG_SND_SOC_MT6366)	+= snd-soc-mt6358.o
>>>    obj-$(CONFIG_SND_SOC_MT6660)	+= snd-soc-mt6660.o
>>>    obj-$(CONFIG_SND_SOC_NAU8315)   += snd-soc-nau8315.o
>>>    obj-$(CONFIG_SND_SOC_NAU8540)   += snd-soc-nau8540.o
>>
>>
>
AngeloGioacchino Del Regno March 7, 2022, 9:14 a.m. UTC | #26
Il 05/03/22 09:58, Jiaxin Yu ha scritto:
> On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
>> Il 17/02/22 14:42, Jiaxin Yu ha scritto:
>>> This patch adds support for mt8186 board with mt6366, da7219 and
>>> max98357.
>>>
>>> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> ---
>>>    .../mt8186/mt8186-mt6366-da7219-max98357.c    | 910
>>> ++++++++++++++++++
>>>    1 file changed, 910 insertions(+)
>>>    create mode 100644 sound/soc/mediatek/mt8186/mt8186-mt6366-
>>> da7219-max98357.c
>>>
>>> diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-
>>> max98357.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-
>>> max98357.c
>>> new file mode 100644
>>> index 000000000000..6ba53b8d1e46
>>> --- /dev/null
>>> +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c
>>> @@ -0,0 +1,910 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +//
>>> +// mt8186-mt6366-da7219-max98357.c
>>> +//	--  MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine driver
>>> +//
>>> +// Copyright (c) 2022 MediaTek Inc.
>>> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> +//
>>> +
>>> +#include <linux/input.h>
>>> +#include <linux/module.h>
>>> +#include <linux/pm_runtime.h>
>>> +#include <sound/pcm_params.h>
>>> +#include <sound/soc.h>
>>> +
>>> +#include "../../codecs/da7219-aad.h"
>>> +#include "../../codecs/da7219.h"
>>> +#include "../../codecs/mt6358.h"
>>> +#include "../common/mtk-afe-platform-driver.h"
>>> +#include "mt8186-afe-common.h"
>>> +#include "mt8186-afe-clk.h"
>>> +#include "mt8186-afe-gpio.h"
>>> +
>>> +#define DA7219_CODEC_DAI "da7219-hifi"
>>> +#define DA7219_DEV_NAME "da7219.5-001a"
>>> +
>>> +struct mt8186_mt6366_da7219_max98357_priv {
>>> +	struct snd_soc_jack headset_jack, hdmi_jack;
>>> +};
>>> +
>>> +static struct snd_soc_codec_conf mt6366_codec_conf[] = {
>>> +	{
>>> +		.dlc = COMP_CODEC_CONF("mt6358-sound"),
>>> +		.name_prefix = "Mt6366",
>>> +	},
>>> +};
>>> +
>>> +static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd)
>>> +{
>>> +	struct mt8186_mt6366_da7219_max98357_priv *priv =
>>> +		snd_soc_card_get_drvdata(rtd->card);
>>> +	struct snd_soc_jack *jack = &priv->headset_jack;
>>> +	struct snd_soc_component *cmpnt_codec =
>>> +		asoc_rtd_to_codec(rtd, 0)->component;
>>> +	int ret;
>>> +
>>> +	/* Enable Headset and 4 Buttons Jack detection */
>>> +	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
>>> +				    SND_JACK_HEADSET | SND_JACK_BTN_0 |
>>> +				    SND_JACK_BTN_1 | SND_JACK_BTN_2 |
>>> +				    SND_JACK_BTN_3 | SND_JACK_LINEOUT,
>>> +				    jack, NULL, 0);
>>> +	if (ret) {
>>> +		dev_err(rtd->dev, "Headset Jack creation failed: %d\n",
>>> ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
>>> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);
>>> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);
>>> +	snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);
>>> +
>>> +	da7219_aad_jack_det(cmpnt_codec, &priv->headset_jack);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int mt8186_da7219_i2s_hw_params(struct snd_pcm_substream
>>> *substream,
>>> +				       struct snd_pcm_hw_params
>>> *params)
>>> +{
>>> +	struct snd_soc_pcm_runtime *rtd =
>>> asoc_substream_to_rtd(substream);
>>> +	struct snd_soc_dai *codec_dai;
>>> +	unsigned int rate = params_rate(params);
>>> +	unsigned int mclk_fs_ratio = 256;
>>> +	unsigned int mclk_fs = rate * mclk_fs_ratio;
>>> +	unsigned int freq;
>>> +	int ret = 0, j;
>>> +
>>> +	ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), 0,
>>> +				     mclk_fs, SND_SOC_CLOCK_OUT);
>>> +	if (ret < 0)
>>> +		dev_err(rtd->dev, "failed to set cpu dai sysclk\n");
>>
>> Does it really make sense to go on after this failure?
>>
>>> +
>>> +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
>>> +		if (!strcmp(codec_dai->component->name,
>>> DA7219_DEV_NAME)) {
>>> +			ret = snd_soc_dai_set_sysclk(codec_dai,
>>> +						     DA7219_CLKSRC_MCLK
>>> ,
>>> +						     mclk_fs,
>>> +						     SND_SOC_CLOCK_IN);
>>> +			if (ret < 0)
>>> +				dev_err(rtd->dev, "failed to set
>>> sysclk\n");
>>> +
>>
>> I think that going on past this wouldn't make sense as well, as it
>> may result
>> in unexpected behavior... just return a failure here
> 
> Yes, it is.
>>
>>> +			if ((rate % 8000) == 0)
>>> +				freq = DA7219_PLL_FREQ_OUT_98304;
>>> +			else
>>> +				freq = DA7219_PLL_FREQ_OUT_90316;
>>> +
>>> +			ret = snd_soc_dai_set_pll(codec_dai, 0,
>>> +						  DA7219_SYSCLK_PLL_SRM
>>> ,
>>> +						  0, freq);
>>> +			if (ret)
>>> +				dev_err(rtd->dev, "failed to start PLL:
>>> %d\n",
>>> +					ret);
>>
>> and here
> Yes, you are right.
> 
>>
>>> +		}
>>> +	}
>>> +
>>
>> So, you've covered all failure cases already, for which, you can
>> simply
>> return 0 here.
> Yes, it is.
> 
>>
>>> +	return ret;
>>> +}
>>> +
>>> +static int mt8186_da7219_i2s_hw_free(struct snd_pcm_substream
>>> *substream)
>>> +{
>>> +	struct snd_soc_pcm_runtime *rtd =
>>> asoc_substream_to_rtd(substream);
>>> +	struct snd_soc_dai *codec_dai;
>>> +	int ret = 0, j;
>>> +
>>> +	for_each_rtd_codec_dais(rtd, j, codec_dai) {
>>> +		if (!strcmp(codec_dai->component->name,
>>> DA7219_DEV_NAME)) {
>>> +			ret = snd_soc_dai_set_pll(codec_dai,
>>> +						  0,
>>> DA7219_SYSCLK_MCLK, 0, 0);
>>> +			if (ret < 0) {
>>> +				dev_err(rtd->dev, "failed to stop PLL:
>>> %d\n",
>>> +					ret);
>>> +				break;
>>> +			}
>>> +		}
>>> +	}
>>> +
>>> +	return ret;
>>> +}
>>> +
>>> +static const struct snd_soc_ops mt8186_da7219_i2s_ops = {
>>> +	.hw_params = mt8186_da7219_i2s_hw_params,
>>> +	.hw_free = mt8186_da7219_i2s_hw_free,
>>> +};
>>> +
>>> +static int mt8186_mt6366_hdmi_init(struct snd_soc_pcm_runtime
>>> *rtd)
>>> +{
>>> +	struct snd_soc_component *cmpnt_codec =
>>> +		asoc_rtd_to_codec(rtd, 0)->component;
>>> +	struct mt8186_mt6366_da7219_max98357_priv *priv =
>>> +		snd_soc_card_get_drvdata(rtd->card);
>>> +	int ret;
>>> +
>>> +	ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack",
>>> SND_JACK_LINEOUT,
>>> +				    &priv->hdmi_jack, NULL, 0);
>>> +	if (ret) {
>>> +		dev_err(rtd->dev, "HDMI Jack creation failed: %d\n",
>>> ret);
>>> +		return ret;
>>> +	}
>>> +
>>> +	return snd_soc_component_set_jack(cmpnt_codec, &priv-
>>>> hdmi_jack, NULL);
>>> +}
>>> +
>>> +static int mt8186_mt6366_init(struct snd_soc_pcm_runtime *rtd)
>>> +{
>>> +	struct snd_soc_component *cmpnt_afe =
>>> +		snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
>>> +	struct snd_soc_component *cmpnt_codec =
>>> +		asoc_rtd_to_codec(rtd, 0)->component;
>>> +	struct mtk_base_afe *afe =
>>> snd_soc_component_get_drvdata(cmpnt_afe);
>>> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
>>> +	struct snd_soc_dapm_context *dapm = &rtd->card->dapm;
>>> +	int ret;
>>> +
>>> +	/* set mtkaif protocol */
>>> +	mt6358_set_mtkaif_protocol(cmpnt_codec,
>>> +				   MT6358_MTKAIF_PROTOCOL_1);
>>> +	afe_priv->mtkaif_protocol = MT6358_MTKAIF_PROTOCOL_1;
>>> +
>>> +	ret = snd_soc_dapm_sync(dapm);
>>> +	if (ret) {
>>> +		dev_info(rtd->dev, "failed to snd_soc_dapm_sync\n");
>>
>> dev_err()
>>
>>> +		return ret;
>>> +	}
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
>>> *rtd,
>>> +				      struct snd_pcm_hw_params *params)
>>> +{
>>> +	struct snd_interval *channels = hw_param_interval(params,
>>> +		SNDRV_PCM_HW_PARAM_CHANNELS);
>>> +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
>>> +
>>
>> dev_dbg()
>>
>>> +	/* fix BE i2s channel to 2 channel */
>>> +	channels->min = 2;
>>> +	channels->max = 2;
>>> +
>>> +	/* fix BE i2s format to S32_LE, clean param mask first */
>>> +	snd_mask_reset_range(hw_param_mask(params,
>>> SNDRV_PCM_HW_PARAM_FORMAT),
>>> +			     0, (__force unsigned
>>> int)SNDRV_PCM_FORMAT_LAST);
>>> +
>>> +	params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int mt8186_hdmi_i2s_hw_params_fixup(struct
>>> snd_soc_pcm_runtime *rtd,
>>> +					   struct snd_pcm_hw_params
>>> *params)
>>> +{
>>> +	struct snd_interval *channels = hw_param_interval(params,
>>> +		SNDRV_PCM_HW_PARAM_CHANNELS);
>>> +	dev_info(rtd->dev, "%s(), fix format to 32bit\n", __func__);
>>> +
>>
>> dev_dbg()
>>
>>> +	/* fix BE i2s channel to 2 channel */
>>> +	channels->min = 2;
>>> +	channels->max = 2;
>>> +
>>> +	/* fix BE i2s format to S24_LE, clean param mask first */
>>> +	snd_mask_reset_range(hw_param_mask(params,
>>> SNDRV_PCM_HW_PARAM_FORMAT),
>>> +			     0, (__force unsigned
>>> int)SNDRV_PCM_FORMAT_LAST);
>>> +
>>> +	params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
>>> +
>>> +	return 0;
>>> +}
>>
> 
> Ok, I will use this code which is really more concise.
> 
>> Besides, I would do the following instead:
>>
>> static int mt8186_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
>>
>> 				  struct snd_pcm_hw_params *params,
>>
>> 				  snd_pcm_format_t fmt)
>>
>> {
>>
>> 	struct snd_interval *channels = hw_param_interval(params,
>>
>> 		SNDRV_PCM_HW_PARAM_CHANNELS);
>>
>> 	dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__);
>>
>>
>>
>> 	/* fix BE i2s channel to 2 channel */
>>
>> 	channels->min = 2;
>>
>> 	channels->max = 2;
>>
>>
>>
>> 	/* fix BE i2s format to S32_LE, clean param mask first */
>>
>> 	snd_mask_reset_range(hw_param_mask(params,
>> SNDRV_PCM_HW_PARAM_FORMAT),
>>
>> 			     0, (__force unsigned
>> int)SNDRV_PCM_FORMAT_LAST);
>>
>>
>>
>> 	params_set_format(params, fmt);
>>
>>
>>
>> 	return 0;
>>
>> }
>>
>>
>>
>> static int mt8186_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
>> *rtd,
>>
>> 				      struct snd_pcm_hw_params *params)
>>
>> {
>>
>> 	return mt8186_hw_params_fixup(rtd, params,
>> SNDRV_PCM_FORMAT_S32_LE);
>>
>> }
>>
>>
>>
>> static int mt8186_hdmi_i2s_hw_params_fixup(struct snd_soc_pcm_runtime
>> *rtd,
>>
>> 					   struct snd_pcm_hw_params
>> *params)
>>
>> {
>>
>> 	return mt8186_hw_params_fixup(rtd, params,
>> SNDRV_PCM_FORMAT_S24_LE);
>>
>> }
>>
>> ... this reduces code duplication!
>>
>>> +
>>> +/* FE */
>>> +SND_SOC_DAILINK_DEFS(playback1,
>>> +		     DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
>>> +		     DAILINK_COMP_ARRAY(COMP_DUMMY()),
>>> +		     DAILINK_COMP_ARRAY(COMP_EMPTY()));
>>
>>
>> ..snip..
>>
>>> +static int mt8186_mt6366_da7219_max98357_dev_probe(struct
>>> platform_device *pdev)
>>> +{
>>> +	struct snd_soc_card *card =
>>> &mt8186_mt6366_da7219_max98357_soc_card;
>>> +	struct snd_soc_dai_link *dai_link;
>>> +	struct mt8186_mt6366_da7219_max98357_priv *priv;
>>> +	struct device_node *platform_node, *hdmi_codec;
>>> +	int ret, i;
>>> +
>>> +	dev_info(&pdev->dev, "%s(), ++\n", __func__);
>>> +
>>> +	card->dev = &pdev->dev;
>>> +
>>> +	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
>>> +	if (!priv)
>>> +		return -ENOMEM;
>>> +
>>> +	platform_node = of_parse_phandle(pdev->dev.of_node,
>>> +					 "mediatek,platform", 0);
>>> +	if (!platform_node) {
>>> +		dev_info(&pdev->dev,
>>> +			 "Property 'platform' missing or invalid\n");
>>
>> 	if (!platform_node)
>> 		return dev_err_probe(&pdev->dev, -EINVAL,
>> 				    "mediatek,platform missing or
>> invalid\n");
>>
>>> +		return -EINVAL;
> got err_platform_node;
>>> +	}
>>> +
>>> +	hdmi_codec = of_parse_phandle(pdev->dev.of_node,
>>> +				      "mediatek,hdmi-codec", 0);
>>> +	if (!hdmi_codec) {
>>> +		dev_info(&pdev->dev,
>>> +			 "Property 'hdmi' missing or invalid\n");
>>
>> dev_err()
>>
>>> +		return -EINVAL;
>>> +	}
> Should I of_node_put(platform_node) befor return?
> 
> goto err_hdmi_node;
> 

of_node_put() has to be called only when of_parse_phandle() succeeds,
otherwise there is nothing to put.

> 
>>> +
>>> +	for_each_card_prelinks(card, i, dai_link) {
>>> +		if (dai_link->platforms->name)
>>> +			continue;
>>> +
>>> +		if (hdmi_codec && strcmp(dai_link->name, "I2S3") == 0)
>>> {
>>> +			dai_link->codecs->of_node = hdmi_codec;
>>> +			dai_link->ignore = 0;
>>> +		}
>>> +
>>> +		dai_link->platforms->of_node = platform_node;
>>> +	}
>>> +
>>> +	snd_soc_card_set_drvdata(card, priv);
>>> +
>>> +	/* init gpio */
>>> +	ret = mt8186_afe_gpio_init(&pdev->dev);
>>> +	if (ret)
>>> +		dev_info(&pdev->dev, "init gpio error\n");
>>
>> dev_err() and goto end;
> Yes, goto err_init_gpio and of_node_put for hdmi_codec and
> platform_node.

Yes, agreed.


Regards,
Angelo

>>
>>> +
>>> +	dev_info(&pdev->dev, "%s(), devm_snd_soc_register_card\n",
>>> __func__);
>>> +	ret = devm_snd_soc_register_card(&pdev->dev, card);
>>> +	if (ret)
>>> +		dev_info(&pdev->dev, "%s snd_soc_register_card fail
>>> %d\n",
>>> +			 __func__, ret);
>>
>> dev_err_probe()
>>
>> end:
>>
> err_init_gpio:
>>> +	of_node_put(hdmi_codec);
> err_hdmi_node:
>>> +	of_node_put(platform_node);
>>> +
> err_platform_node:
>>> +	return ret;
>>> +}
>>> +
>>> +#if IS_ENABLED(CONFIG_OF)
>>> +static const struct of_device_id
>>> mt8186_mt6366_da7219_max98357_dt_match[] = {
>>> +	{.compatible =
>>> "mediatek,mt8186_mt6366_da7219_max98357_sound",},
>>> +	{}
>>> +};
>>> +#endif
>>> +
>>> +static struct platform_driver mt8186_mt6366_da7219_max98357_driver
>>> = {
>>> +	.driver = {
>>> +		.name = "mt8186_mt6366_da7219_max98357",
>>> +#if IS_ENABLED(CONFIG_OF)
>>> +		.of_match_table =
>>> mt8186_mt6366_da7219_max98357_dt_match,
>>> +#endif
>>> +		.pm = &snd_soc_pm_ops,
>>> +	},
>>> +	.probe = mt8186_mt6366_da7219_max98357_dev_probe,
>>> +};
>>> +
>>> +module_platform_driver(mt8186_mt6366_da7219_max98357_driver);
>>> +
>>> +/* Module information */
>>> +MODULE_DESCRIPTION("MT8186-MT6366-DA7219-MAX98357 ALSA SoC machine
>>> driver");
>>> +MODULE_AUTHOR("Jiaxin Yu <jiaxin.yu@mediatek.com>");
>>> +MODULE_LICENSE("GPL v2");
>>> +MODULE_ALIAS("mt8186_mt6366_da7219_max98357 soc card");
>>
>>
>
AngeloGioacchino Del Regno March 7, 2022, 9:25 a.m. UTC | #27
Il 05/03/22 11:49, Jiaxin Yu ha scritto:
> On Fri, 2022-02-18 at 15:54 +0100, AngeloGioacchino Del Regno wrote:
>> Il 17/02/22 14:41, Jiaxin Yu ha scritto:
>>> This patch adds mt8186 adda dai driver
>>>
>>> Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> ---
>>>    sound/soc/mediatek/mt8186/mt8186-dai-adda.c | 891
>>> ++++++++++++++++++++
>>>    1 file changed, 891 insertions(+)
>>>    create mode 100644 sound/soc/mediatek/mt8186/mt8186-dai-adda.c
>>>
>>> diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
>>> b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
>>> new file mode 100644
>>> index 000000000000..6d7dd1533da0
>>> --- /dev/null
>>> +++ b/sound/soc/mediatek/mt8186/mt8186-dai-adda.c
>>> @@ -0,0 +1,891 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +//
>>> +// MediaTek ALSA SoC Audio DAI ADDA Control
>>> +//
>>> +// Copyright (c) 2022 MediaTek Inc.
>>> +// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
>>> +
>>> +#include <linux/regmap.h>
>>> +#include <linux/delay.h>
>>> +#include "mt8186-afe-clk.h"
>>> +#include "mt8186-afe-common.h"
>>> +#include "mt8186-afe-gpio.h"
>>> +#include "mt8186-interconnection.h"
>>> +
> ...snip...
>>>
>>> +/* dai ops */
>>> +static int mtk_dai_adda_hw_params(struct snd_pcm_substream
>>> *substream,
>>> +				  struct snd_pcm_hw_params *params,
>>> +				  struct snd_soc_dai *dai)
>>> +{
>>> +	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
>>> +	struct mt8186_afe_private *afe_priv = afe->platform_priv;
>>> +	unsigned int rate = params_rate(params);
>>> +	int id = dai->id;
>>> +	struct mtk_afe_adda_priv *adda_priv = afe_priv->dai_priv[id];
>>> +
>>> +	dev_info(afe->dev, "%s(), id %d, stream %d, rate %d\n",
>>> +		 __func__,
>>> +		 id,
>>> +		 substream->stream,
>>> +		 rate);
>>> +
>>> +	if (!adda_priv) {
>>> +		dev_info(afe->dev, "%s(), adda_priv == NULL",
>>> __func__);
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>>> +		unsigned int dl_src2_con0 = 0;
>>> +		unsigned int dl_src2_con1 = 0;
>>
>> This initialization is redundant: you're never using these variables
>> before initializing them later, so initializing them to zero is not
>> needed here.
> Yes, got it. Thank you.
>>
>>> +
>>> +		adda_priv->dl_rate = rate;
>>> +
>>> +		/* set sampling rate */
>>> +		dl_src2_con0 = adda_dl_rate_transform(afe, rate) <<
>>> +			       DL_2_INPUT_MODE_CTL_SFT;
>>> +
>>> +		/* set output mode, UP_SAMPLING_RATE_X8 */
>>> +		dl_src2_con0 |= (0x3 << DL_2_OUTPUT_SEL_CTL_SFT);
>>> +
>>> +		/* turn off mute function */
>>> +		dl_src2_con0 |= (0x01 <<
>>> DL_2_MUTE_CH2_OFF_CTL_PRE_SFT);
>>
>> BIT() macro, please
>>
>>> +		dl_src2_con0 |= (0x01 <<
>>> DL_2_MUTE_CH1_OFF_CTL_PRE_SFT);
>>> +
>>> +		/* set voice input data if input sample rate is 8k or
>>> 16k */
>>> +		if (rate == 8000 || rate == 16000)
>>> +			dl_src2_con0 |= 0x01 <<
>>> DL_2_VOICE_MODE_CTL_PRE_SFT;
>>> +
>>> +		/* SA suggest apply -0.3db to audio/speech path */
>>> +		dl_src2_con1 = MTK_AFE_ADDA_DL_GAIN_NORMAL <<
>>> +			       DL_2_GAIN_CTL_PRE_SFT;
>>> +
>>> +		/* turn on down-link gain */
>>> +		dl_src2_con0 |= (0x01 << DL_2_GAIN_ON_CTL_PRE_SFT);
>>> +
>>> +		if (id == MT8186_DAI_ADDA) {
>>> +			/* clean predistortion */
>>> +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON0,
>>> 0);
>>> +			regmap_write(afe->regmap, AFE_ADDA_PREDIS_CON1,
>>> 0);
>>> +
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_DL_SRC2_CON0,
>>> dl_src2_con0);
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_DL_SRC2_CON1,
>>> dl_src2_con1);
>>> +
>>> +			/* set sdm gain */
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
>>> +					   ATTGAIN_CTL_MASK_SFT,
>>> +					   AUDIO_SDM_LEVEL_NORMAL <<
>>> +					   ATTGAIN_CTL_SFT);
>>> +
>>> +			/* Use new 2nd sdm */
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_DL_SDM_DITHER_CON,
>>> +					   AFE_DL_SDM_DITHER_64TAP_EN_M
>>> ASK_SFT,
>>> +					   0x1 <<
>>> AFE_DL_SDM_DITHER_64TAP_EN_SFT);
>>
>> BIT(AFE_DL_SDM_DITHER_64TAP_EN_SFT)
>>
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_DL_SDM_AUTO_RESET_C
>>> ON,
>>> +					   AFE_DL_USE_NEW_2ND_SDM_MASK_
>>> SFT,
>>> +					   0x1 <<
>>> AFE_DL_USE_NEW_2ND_SDM_SFT);
>>
>> BIT(AFE_DL_USE_NEW_2ND_SDM_SFT)
>>
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_DL_SDM_DCCOMP_CON,
>>> +					   USE_3RD_SDM_MASK_SFT,
>>> +					   AUDIO_SDM_2ND <<
>>> USE_3RD_SDM_SFT);
>>> +
>>> +			/* sdm auto reset */
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_DL_SDM_AUTO_RESET_CON,
>>> +				     SDM_AUTO_RESET_THRESHOLD);
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_DL_SDM_AUTO_RESET_C
>>> ON,
>>> +					   SDM_AUTO_RESET_TEST_ON_MASK_
>>> SFT,
>>> +					   0x1 <<
>>> SDM_AUTO_RESET_TEST_ON_SFT);
>>
>> BIT(SDM_AUTO_RESET_TEST_ON_SFT)
>>
>>> +		}
>>> +	} else {
>>> +		unsigned int voice_mode = 0;
>>
>> what about...
>> 		unsigned int ul_src_con0 = 0; /* default value */
>> 		unsigned int voice_mode =  adda_ul_rate_transform(afe,
>> rate);
> Agree with you.
> 
>>> +		unsigned int ul_src_con0 = 0;	/* default value */
>>> +
>>> +		adda_priv->ul_rate = rate;
>>> +
>>> +		voice_mode = adda_ul_rate_transform(afe, rate);
>>> +
>>> +		ul_src_con0 |= (voice_mode << 17) & (0x7 << 17);
>>> +
>>> +		/* enable iir */
>>> +		ul_src_con0 |= (1 << UL_IIR_ON_TMP_CTL_SFT) &
>>> +			       UL_IIR_ON_TMP_CTL_MASK_SFT;
>>> +		ul_src_con0 |= (UL_IIR_SW << UL_IIRMODE_CTL_SFT) &
>>> +			       UL_IIRMODE_CTL_MASK_SFT;
>>> +		switch (id) {
>>> +		case MT8186_DAI_ADDA:
>>> +		case MT8186_DAI_AP_DMIC:
>>> +			/* 35Hz @ 48k */
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_IIR_COEF_02_01,
>>> 0x00000000);
>>
>> Please drop leading zeroes:
>>
>> regmap_write(afe->regmap, AFE_ADDA_IIR_COEF_02_01, 0);
>>
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_IIR_COEF_04_03,
>>> 0x00003FB8);
>>
>> ... and also please write hex in lower-case:
>>
> Got it.
>> regmap_write(afe->regmap,
>> 	     AFE_ADDA_IIR_COEF_04_03, 0x03fb8);
>>
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_IIR_COEF_06_05,
>>> 0x3FB80000);
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_IIR_COEF_08_07,
>>> 0x3FB80000);
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_IIR_COEF_10_09,
>>> 0x0000C048);
>>> +
>>> +			regmap_write(afe->regmap,
>>> +				     AFE_ADDA_UL_SRC_CON0,
>>> ul_src_con0);
>>> +
>>> +			/* Using Internal ADC */
>>> +			regmap_update_bits(afe->regmap,
>>> +					   AFE_ADDA_TOP_CON0,
>>> +					   0x1 << 0,
>>> +					   0x0 << 0);
>>
>> Please use the BIT() macro:
>>
>> regmap_update_bits(afe->regmap, AFE_ADDA_TOP_CON0, BIT(0), 0);
>>
>> P.S.: 87 columns is ok
> 
> How can I judge whether it can exceed 80 lines?

https://www.kernel.org/doc/html/latest/process/coding-style.html

Besides, the 80 columns rule was made for old terminals (like VT100 and such)
that supported displaying a maximum of 80 cols... in the modern era, that's
not the case anymore.
It's somewhat preferred if something can fit in 80 columns, but if it does
impact on readability, then you can go over that, up to 100 columns.

scripts/checkpatch.pl was also changed to complain about 100 columns and not
80 anymore...

my $max_line_length = 100;

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/scripts/checkpatch.pl?h=v5.17-rc7#n59

Cheers,
Angelo