/*
 * Copyright (c) 2022 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <errno.h>
#include <zephyr/spinlock.h>

#define LOG_DOMAIN dai_intel_dmic_nhlt
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_DOMAIN);

#include <zephyr/drivers/dai.h>
#include <adsp_clk.h>
#include "dmic.h"
#include <dmic_regs.h>
#include "dmic_nhlt.h"

extern struct dai_dmic_global_shared dai_dmic_global;

/* Base addresses (in PDM scope) of 2ch PDM controllers and coefficient RAM. */
static const uint32_t dmic_base[4] = {PDM0, PDM1, PDM2, PDM3};

static inline void dai_dmic_write(const struct dai_intel_dmic *dmic,
				  uint32_t reg, uint32_t val)
{
	sys_write32(val, dmic->reg_base + reg);
}

static inline uint32_t dai_dmic_read(const struct dai_intel_dmic *dmic, uint32_t reg)
{
	return sys_read32(dmic->reg_base + reg);
}

/*
 * @brief Move pointer to next coefficient data
 *
 * @return Returns pointer right after coefficient data
 */
static const uint32_t *dai_dmic_skip_coeff(const uint32_t *coeff, const int length,
					   const bool packed)
{
	if (!packed) {
		coeff += length;
	} else {
		coeff += ROUND_UP(3 * length, sizeof(uint32_t)) / sizeof(uint32_t);
	}

	return coeff;
}

/*
 * @brief Write the fir coefficients in the PDMs' RAM
 */
static void dai_dmic_write_coeff(const struct dai_intel_dmic *dmic, uint32_t base,
				 const uint32_t *coeff, int length, const bool packed)
{
	const uint8_t *coeff_in_bytes;
	uint32_t coeff_val;

	if (!packed) {
		while (length--) {
			dai_dmic_write(dmic, base, *coeff++);
			base += sizeof(uint32_t);
		}
	} else {
		coeff_in_bytes = (const uint8_t *)coeff;

		while (length--) {
			coeff_val = coeff_in_bytes[0] +
				(coeff_in_bytes[1] << 8) +
				(coeff_in_bytes[2] << 16);

			dai_dmic_write(dmic, base, coeff_val);
			base += sizeof(uint32_t);

			coeff_in_bytes += 3;
		}
	}
}

/*
 * @brief Configures the fir coefficients in the PDMs' RAM
 *
 * @return Returns pointer right after coefficients data
 */
static const uint32_t *dai_dmic_configure_coeff(const struct dai_intel_dmic *dmic,
						const struct nhlt_pdm_ctrl_cfg * const pdm_cfg,
						const uint32_t pdm_base,
						const uint32_t *coeffs)
{
	int fir_length_a, fir_length_b;
	bool packed = false;
	const uint32_t *coeffs_b;

	fir_length_a = FIELD_GET(FIR_CONFIG_FIR_LENGTH, pdm_cfg->fir_config[0].fir_config) + 1;
	fir_length_b = FIELD_GET(FIR_CONFIG_FIR_LENGTH, pdm_cfg->fir_config[1].fir_config) + 1;

	if (fir_length_a > 256 || fir_length_b > 256) {
		LOG_ERR("invalid coeff length! %d %d", fir_length_a, fir_length_b);
		return NULL;
	}

	if (*coeffs == FIR_COEFFS_PACKED_TO_24_BITS) {
		packed = true;

		/* First dword is not included into length_0 and length_1 - skip it. */
		coeffs++;
	}

	coeffs_b = dai_dmic_skip_coeff(coeffs, fir_length_a, packed);

	LOG_INF("fir_length_a = %d, fir_length_b = %d, packed = %d", fir_length_a, fir_length_b,
		packed);

	if (dmic->dai_config_params.dai_index == 0) {
		dai_dmic_write_coeff(dmic, pdm_base + PDM_COEFFICIENT_A, coeffs, fir_length_a,
				     packed);
	} else {
		dai_dmic_write_coeff(dmic, pdm_base + PDM_COEFFICIENT_B, coeffs_b, fir_length_b,
				     packed);
	}

	return dai_dmic_skip_coeff(coeffs_b, fir_length_b, packed);
}

static int dai_nhlt_get_clock_div(const struct dai_intel_dmic *dmic, const int pdm)
{
	uint32_t val;
	int p_mcic, p_clkdiv, p_mfir, rate_div;

	val = dai_dmic_read(dmic, dmic_base[pdm] + CIC_CONFIG);
	p_mcic = FIELD_GET(CIC_CONFIG_COMB_COUNT, val) + 1;

	val = dai_dmic_read(dmic, dmic_base[pdm] + MIC_CONTROL);
	p_clkdiv = FIELD_GET(MIC_CONTROL_PDM_CLKDIV, val) + 2;

	val = dai_dmic_read(dmic, dmic_base[pdm] +
			    FIR_CHANNEL_REGS_SIZE * dmic->dai_config_params.dai_index + FIR_CONFIG);
	LOG_INF("pdm = %d, FIR_CONFIG = 0x%08X", pdm, val);

	p_mfir = FIELD_GET(FIR_CONFIG_FIR_DECIMATION, val) + 1;

	rate_div = p_clkdiv * p_mcic * p_mfir;
	LOG_INF("dai_index = %d, rate_div = %d, p_clkdiv = %d, p_mcic = %d, p_mfir = %d",
		dmic->dai_config_params.dai_index, rate_div, p_clkdiv, p_mcic, p_mfir);

	if (!rate_div) {
		LOG_ERR("zero clock divide or decimation factor");
		return -EINVAL;
	}

	return rate_div;
}

static int dai_nhlt_update_rate(struct dai_intel_dmic *dmic, const int clock_source, const int pdm)
{
	int rate_div;

	rate_div = dai_nhlt_get_clock_div(dmic, pdm);
	if (rate_div < 0) {
		return rate_div;
	}

	dmic->dai_config_params.rate = adsp_clock_source_frequency(clock_source) /
		rate_div;

	LOG_INF("rate = %d, channels = %d, format = %d",
		dmic->dai_config_params.rate, dmic->dai_config_params.channels,
		dmic->dai_config_params.format);

	LOG_INF("io_clk %u, rate_div %d", adsp_clock_source_frequency(clock_source), rate_div);
	return 0;
}

#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
static int dai_ipm_source_to_enable(struct dai_intel_dmic *dmic,
				    int *count, int pdm_count, int stereo,
				    int source_pdm)
{
	int mic_swap;

	if (source_pdm >= CONFIG_DAI_DMIC_HW_CONTROLLERS)
		return -EINVAL;

	if (*count < pdm_count) {
		(*count)++;
		mic_swap = FIELD_GET(MIC_CONTROL_CLK_EDGE, dai_dmic_read(
						dmic, dmic_base[source_pdm] + MIC_CONTROL));
		if (stereo)
			dmic->enable[source_pdm] = 0x3; /* PDMi MIC A and B */
		else
			dmic->enable[source_pdm] = mic_swap ? 0x2 : 0x1; /* PDMi MIC B or MIC A */
	}

	return 0;
}

static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic, const int clock_source)
{
	bool stereo_pdm;
	int source_pdm;
	int first_pdm;
	int num_pdm;
	int ret;
	int n;
	uint32_t outcontrol_val = dai_dmic_read(dmic, dmic->dai_config_params.dai_index *
						PDM_CHANNEL_REGS_SIZE + OUTCONTROL);

	switch (FIELD_GET(OUTCONTROL_OF, outcontrol_val)) {
	case 0:
	case 1:
		dmic->dai_config_params.format = DAI_DMIC_FRAME_S16_LE;
		dmic->dai_config_params.word_size = 16;
		break;
	case 2:
		dmic->dai_config_params.format = DAI_DMIC_FRAME_S32_LE;
		dmic->dai_config_params.word_size = 32;
		break;
	default:
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal OF bit field");
		return -EINVAL;
	}

	num_pdm = FIELD_GET(OUTCONTROL_IPM, outcontrol_val);
	if (num_pdm > CONFIG_DAI_DMIC_HW_CONTROLLERS) {
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM PDM controllers count %d",
			num_pdm);
		return -EINVAL;
	}

	stereo_pdm = FIELD_GET(OUTCONTROL_IPM_SOURCE_MODE, outcontrol_val);

	dmic->dai_config_params.channels = (stereo_pdm + 1) * num_pdm;
	for (n = 0; n < CONFIG_DAI_DMIC_HW_CONTROLLERS; n++)
		dmic->enable[n] = 0;

	n = 0;
	source_pdm = FIELD_GET(OUTCONTROL_IPM_SOURCE_1, outcontrol_val);
	first_pdm = source_pdm;
	ret = dai_ipm_source_to_enable(dmic, &n, num_pdm, stereo_pdm, source_pdm);
	if (ret) {
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM_SOURCE_1");
		return -EINVAL;
	}

	source_pdm = FIELD_GET(OUTCONTROL_IPM_SOURCE_2, outcontrol_val);
	ret = dai_ipm_source_to_enable(dmic, &n, num_pdm, stereo_pdm, source_pdm);
	if (ret) {
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM_SOURCE_2");
		return -EINVAL;
	}

	source_pdm = FIELD_GET(OUTCONTROL_IPM_SOURCE_3, outcontrol_val);
	ret = dai_ipm_source_to_enable(dmic, &n, num_pdm, stereo_pdm, source_pdm);
	if (ret) {
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM_SOURCE_3");
		return -EINVAL;
	}

	source_pdm = FIELD_GET(OUTCONTROL_IPM_SOURCE_4, outcontrol_val);
	ret = dai_ipm_source_to_enable(dmic, &n, num_pdm, stereo_pdm, source_pdm);
	if (ret) {
		LOG_ERR("nhlt_dmic_dai_params_get(): Illegal IPM_SOURCE_4");
		return -EINVAL;
	}

	return dai_nhlt_update_rate(dmic, clock_source, first_pdm);
}


/*
 * @brief Set clock source used by device
 *
 * @param source Clock source index
 */
static inline void dai_dmic_clock_select_set(const struct dai_intel_dmic *dmic, uint32_t source)
{
	uint32_t val;
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET);
	val &= ~DMICLVSCTL_MLCS;
	val |= FIELD_PREP(DMICLVSCTL_MLCS, source);
	sys_write32(val, dmic->vshim_base + DMICLVSCTL_OFFSET);
#else
	val = sys_read32(dmic->shim_base + DMICLCTL_OFFSET);
	val &= ~DMICLCTL_MLCS;
	val |= FIELD_PREP(DMICLCTL_MLCS, source);
	sys_write32(val, dmic->shim_base + DMICLCTL_OFFSET);
#endif
}

/*
 * @brief Get clock source used by device
 *
 * @return Clock source index
 */
static inline uint32_t dai_dmic_clock_select_get(const struct dai_intel_dmic *dmic)
{
	uint32_t val;
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	val = sys_read32(dmic->vshim_base + DMICLVSCTL_OFFSET);
	return FIELD_GET(DMICLVSCTL_MLCS, val);
#else
	val = sys_read32(dmic->shim_base + DMICLCTL_OFFSET);
	return FIELD_GET(DMICLCTL_MLCS, val);
#endif
}

/*
 * @brief Set clock source used by device
 *
 * @param source Clock source index
 */
static int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t clock_source)
{
	LOG_DBG("%s(): clock_source = %u", __func__, clock_source);

	if (!adsp_clock_source_is_supported(clock_source)) {
		return -ENOTSUP;
	}

#ifndef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	if (clock_source && !(sys_read32(dmic->shim_base + DMICLCAP_OFFSET) & DMICLCAP_MLCS)) {
		return -ENOTSUP;
	}
#endif

	dai_dmic_clock_select_set(dmic, clock_source);
	return 0;
}
#else
static int dai_nhlt_dmic_dai_params_get(struct dai_intel_dmic *dmic)
{
	uint32_t outcontrol;
	uint32_t fir_control[2];
	uint32_t mic_control[2];

	int fir_stereo[2];
	int mic_swap;

	outcontrol = dai_dmic_read(dmic, dmic->dai_config_params.dai_index * PDM_CHANNEL_REGS_SIZE +
				   OUTCONTROL);

	switch (FIELD_GET(OUTCONTROL_OF, outcontrol)) {
	case 0:
	case 1:
		dmic->dai_config_params.format = DAI_DMIC_FRAME_S16_LE;
		break;
	case 2:
		dmic->dai_config_params.format = DAI_DMIC_FRAME_S32_LE;
		break;
	default:
		LOG_ERR("Illegal OF bit field");
		return -EINVAL;
	}

	fir_control[0] = dai_dmic_read(dmic, dmic_base[0] +
				       dmic->dai_config_params.dai_index * FIR_CHANNEL_REGS_SIZE +
				       FIR_CONTROL);

	fir_control[1] = dai_dmic_read(dmic, dmic_base[1] +
				       dmic->dai_config_params.dai_index * FIR_CHANNEL_REGS_SIZE +
				       FIR_CONTROL);

	mic_control[0] = dai_dmic_read(dmic, dmic_base[0] + MIC_CONTROL);
	mic_control[1] = dai_dmic_read(dmic, dmic_base[1] + MIC_CONTROL);

	switch (FIELD_GET(OUTCONTROL_IPM, outcontrol)) {
	case 0:
		fir_stereo[0] = FIELD_GET(FIR_CONTROL_STEREO, fir_control[0]);
		if (fir_stereo[0]) {
			dmic->dai_config_params.channels = 2;
			dmic->enable[0] = 0x3; /* PDM0 MIC A and B */
			dmic->enable[1] = 0x0;	/* PDM1 none */

		} else {
			dmic->dai_config_params.channels = 1;
			mic_swap = FIELD_GET(MIC_CONTROL_CLK_EDGE, mic_control[0]);
			dmic->enable[0] = mic_swap ? 0x2 : 0x1; /* PDM0 MIC B or MIC A */
			dmic->enable[1] = 0x0;	/* PDM1 */
		}
		break;
	case 1:
		fir_stereo[1] = FIELD_GET(FIR_CONTROL_STEREO, fir_control[1]);
		if (fir_stereo[1]) {
			dmic->dai_config_params.channels = 2;
			dmic->enable[0] = 0x0; /* PDM0 none */
			dmic->enable[1] = 0x3;	/* PDM1 MIC A and B */
		} else {
			dmic->dai_config_params.channels = 1;
			dmic->enable[0] = 0x0; /* PDM0 none */
			mic_swap = FIELD_GET(MIC_CONTROL_CLK_EDGE, mic_control[1]);
			dmic->enable[1] = mic_swap ? 0x2 : 0x1; /* PDM1 MIC B or MIC A */
		}
		break;
	case 2:
		fir_stereo[0] = FIELD_GET(FIR_CONTROL_STEREO, fir_control[0]);
		fir_stereo[1] = FIELD_GET(FIR_CONTROL_STEREO, fir_control[1]);
		if (fir_stereo[0] == fir_stereo[1]) {
			dmic->dai_config_params.channels = 4;
			dmic->enable[0] = 0x3; /* PDM0 MIC A and B */
			dmic->enable[1] = 0x3;	/* PDM1 MIC A and B */
			LOG_INF("set 4ch pdm0 and pdm1");
		} else {
			LOG_ERR("Illegal 4ch configuration");
			return -EINVAL;
		}
		break;
	default:
		LOG_ERR("Illegal OF bit field");
		return -EINVAL;
	}

	return dai_nhlt_update_rate(dmic, 0, 0);
}

static inline int dai_dmic_set_clock(const struct dai_intel_dmic *dmic, const uint8_t clock_source)
{
	return 0;
}
#endif

static int print_outcontrol(uint32_t val)
{
	int bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8;
#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	int bf9, bf10, bf11, bf12, bf13;
#endif
	uint32_t ref;

	bf1 = FIELD_GET(OUTCONTROL_TIE, val);
	bf2 = FIELD_GET(OUTCONTROL_SIP, val);
	bf3 = FIELD_GET(OUTCONTROL_FINIT, val);
	bf4 = FIELD_GET(OUTCONTROL_FCI, val);
	bf5 = FIELD_GET(OUTCONTROL_BFTH, val);
	bf6 = FIELD_GET(OUTCONTROL_OF, val);
	bf7 = FIELD_GET(OUTCONTROL_IPM, val);
	bf8 = FIELD_GET(OUTCONTROL_TH, val);
	LOG_INF("OUTCONTROL = %08x", val);
	LOG_INF("  tie=%d, sip=%d, finit=%d, fci=%d", bf1, bf2, bf3, bf4);
	LOG_INF("  bfth=%d, of=%d, ipm=%d, th=%d", bf5, bf6, bf7, bf8);
	if (bf5 > OUTCONTROL_BFTH_MAX) {
		LOG_WRN("illegal BFTH value %d", bf5);
		return -EINVAL;
	}

#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	bf9 = FIELD_GET(OUTCONTROL_IPM_SOURCE_1, val);
	bf10 = FIELD_GET(OUTCONTROL_IPM_SOURCE_2, val);
	bf11 = FIELD_GET(OUTCONTROL_IPM_SOURCE_3, val);
	bf12 = FIELD_GET(OUTCONTROL_IPM_SOURCE_4, val);
	bf13 = FIELD_GET(OUTCONTROL_IPM_SOURCE_MODE, val);
	LOG_INF("  ipms1=%d, ipms2=%d, ipms3=%d, ipms4=%d", bf9, bf10, bf11, bf12);
	LOG_INF("  ipms_mode=%d", bf13);
	ref = FIELD_PREP(OUTCONTROL_TIE, bf1) | FIELD_PREP(OUTCONTROL_SIP, bf2) |
		FIELD_PREP(OUTCONTROL_FINIT, bf3) | FIELD_PREP(OUTCONTROL_FCI, bf4) |
		FIELD_PREP(OUTCONTROL_BFTH, bf5) | FIELD_PREP(OUTCONTROL_OF, bf6) |
		FIELD_PREP(OUTCONTROL_IPM, bf7) | FIELD_PREP(OUTCONTROL_IPM_SOURCE_1, bf9) |
		FIELD_PREP(OUTCONTROL_IPM_SOURCE_2, bf10) |
		FIELD_PREP(OUTCONTROL_IPM_SOURCE_3, bf11) |
		FIELD_PREP(OUTCONTROL_IPM_SOURCE_4, bf12) | FIELD_PREP(OUTCONTROL_TH, bf8) |
		FIELD_PREP(OUTCONTROL_IPM_SOURCE_MODE, bf13);
#else
	ref = FIELD_PREP(OUTCONTROL_TIE, bf1) | FIELD_PREP(OUTCONTROL_SIP, bf2) |
		FIELD_PREP(OUTCONTROL_FINIT, bf3) | FIELD_PREP(OUTCONTROL_FCI, bf4) |
		FIELD_PREP(OUTCONTROL_BFTH, bf5) | FIELD_PREP(OUTCONTROL_OF, bf6) |
		FIELD_PREP(OUTCONTROL_IPM, bf7) | FIELD_PREP(OUTCONTROL_TH, bf8);
#endif
	if (ref != val) {
		LOG_WRN("Some reserved bits are set in OUTCONTROL = 0x%08x", val);
	}

	return 0;
}

static void print_cic_control(uint32_t val)
{
	int bf1, bf2, bf3, bf4, bf5, bf6, bf7;
	uint32_t ref;

	bf1 = FIELD_GET(CIC_CONTROL_SOFT_RESET, val);
	bf2 = FIELD_GET(CIC_CONTROL_CIC_START_B, val);
	bf3 = FIELD_GET(CIC_CONTROL_CIC_START_A, val);
	bf4 = FIELD_GET(CIC_CONTROL_MIC_B_POLARITY, val);
	bf5 = FIELD_GET(CIC_CONTROL_MIC_A_POLARITY, val);
	bf6 = FIELD_GET(CIC_CONTROL_MIC_MUTE, val);
#ifndef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	bf7 = FIELD_GET(CIC_CONTROL_STEREO_MODE, val);
#else
	bf7 = -1;
#endif
	LOG_DBG("CIC_CONTROL = %08x", val);
	LOG_DBG("  soft_reset=%d, cic_start_b=%d, cic_start_a=%d",
		bf1, bf2, bf3);
	LOG_DBG("  mic_b_polarity=%d, mic_a_polarity=%d, mic_mute=%d",
		bf4, bf5, bf6);
	ref = FIELD_PREP(CIC_CONTROL_SOFT_RESET, bf1) |
		FIELD_PREP(CIC_CONTROL_CIC_START_B, bf2) |
		FIELD_PREP(CIC_CONTROL_CIC_START_A, bf3) |
		FIELD_PREP(CIC_CONTROL_MIC_B_POLARITY, bf4) |
		FIELD_PREP(CIC_CONTROL_MIC_A_POLARITY, bf5) |
		FIELD_PREP(CIC_CONTROL_MIC_MUTE, bf6)
#ifndef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
		| FIELD_PREP(CIC_CONTROL_STEREO_MODE, bf7)
#endif
		;
	LOG_DBG("  stereo_mode=%d", bf7);
	if (ref != val) {
		LOG_WRN("Some reserved bits are set in CIC_CONTROL = 0x%08x", val);
	}
}

static void print_fir_control(uint32_t val)
{
	int bf1, bf2, bf3, bf4, bf5, bf6;
	uint32_t ref;

	bf1 = FIELD_GET(FIR_CONTROL_START, val);
	bf2 = FIELD_GET(FIR_CONTROL_ARRAY_START_EN, val);
#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	bf3 = FIELD_GET(FIR_CONTROL_PERIODIC_START_EN, val);
#else
	bf3 = -1;
#endif
	bf4 = FIELD_GET(FIR_CONTROL_DCCOMP, val);
	bf5 = FIELD_GET(FIR_CONTROL_MUTE, val);
	bf6 = FIELD_GET(FIR_CONTROL_STEREO, val);
	LOG_DBG("FIR_CONTROL = %08x", val);
	LOG_DBG("  start=%d, array_start_en=%d, periodic_start_en=%d",
		bf1, bf2, bf3);
	LOG_DBG("  dccomp=%d, mute=%d, stereo=%d", bf4, bf5, bf6);
	ref = FIELD_PREP(FIR_CONTROL_START, bf1) |
		FIELD_PREP(FIR_CONTROL_ARRAY_START_EN, bf2) |
#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
		FIELD_PREP(FIR_CONTROL_PERIODIC_START_EN, bf3) |
#endif
		FIELD_PREP(FIR_CONTROL_DCCOMP, bf4) |
		FIELD_PREP(FIR_CONTROL_MUTE, bf5) |
		FIELD_PREP(FIR_CONTROL_STEREO, bf6);

	if (ref != val) {
		LOG_WRN("Some reserved bits are set in FIR_CONTROL = 0x%08x", val);
	}
}

static void print_pdm_ctrl(const struct nhlt_pdm_ctrl_cfg *pdm_cfg)
{
	int bf1, bf2, bf3, bf4, bf5;
	uint32_t val;

	LOG_DBG("CIC_CONTROL = %08x", pdm_cfg->cic_control);

	val = pdm_cfg->cic_config;
	bf1 = FIELD_GET(CIC_CONFIG_CIC_SHIFT, val);
	bf2 = FIELD_GET(CIC_CONFIG_COMB_COUNT, val);
	LOG_DBG("CIC_CONFIG = %08x", val);
	LOG_DBG("  cic_shift=%d, comb_count=%d", bf1, bf2);

	val = pdm_cfg->mic_control;

#ifndef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	bf1 = FIELD_GET(MIC_CONTROL_PDM_SKEW, val);
#else
	bf1 = -1;
#endif
	bf2 = FIELD_GET(MIC_CONTROL_CLK_EDGE, val);
	bf3 = FIELD_GET(MIC_CONTROL_PDM_EN_B, val);
	bf4 = FIELD_GET(MIC_CONTROL_PDM_EN_A, val);
	bf5 = FIELD_GET(MIC_CONTROL_PDM_CLKDIV, val);
	LOG_DBG("MIC_CONTROL = %08x", val);
	LOG_DBG("  clkdiv=%d, skew=%d, clk_edge=%d", bf5, bf1, bf2);
	LOG_DBG("  en_b=%d, en_a=%d", bf3, bf4);
}

static void print_fir_config(const struct nhlt_pdm_ctrl_fir_cfg *fir_cfg)
{
	uint32_t val;
	int fir_decimation, fir_shift, fir_length;

	val = fir_cfg->fir_config;
	fir_length = FIELD_GET(FIR_CONFIG_FIR_LENGTH, val);
	fir_decimation = FIELD_GET(FIR_CONFIG_FIR_DECIMATION, val);
	fir_shift = FIELD_GET(FIR_CONFIG_FIR_SHIFT, val);
	LOG_DBG("FIR_CONFIG = %08x", val);
	LOG_DBG("  fir_decimation=%d, fir_shift=%d, fir_length=%d",
		fir_decimation, fir_shift, fir_length);

	print_fir_control(fir_cfg->fir_control);

	/* Use DC_OFFSET and GAIN as such */
	LOG_DBG("DC_OFFSET_LEFT = %08x", fir_cfg->dc_offset_left);
	LOG_DBG("DC_OFFSET_RIGHT = %08x", fir_cfg->dc_offset_right);
	LOG_DBG("OUT_GAIN_LEFT = %08x", fir_cfg->out_gain_left);
	LOG_DBG("OUT_GAIN_RIGHT = %08x", fir_cfg->out_gain_right);
}

static void configure_fir(struct dai_intel_dmic *dmic, const uint32_t base,
			  const struct nhlt_pdm_ctrl_fir_cfg *fir_cfg)
{
	uint32_t val;

	print_fir_config(fir_cfg);

	/* Use FIR_CONFIG as such */
	val = fir_cfg->fir_config;
	dai_dmic_write(dmic, base + FIR_CONFIG, val);

	val = fir_cfg->fir_control;
	print_fir_control(val);

	/* Clear START, set MUTE */
	val = (val & ~FIR_CONTROL_START) | FIR_CONTROL_MUTE;
	dai_dmic_write(dmic, base + FIR_CONTROL, val);
	LOG_DBG("FIR_CONTROL = %08x", val);

	/* Use DC_OFFSET and GAIN as such */
	dai_dmic_write(dmic, base + DC_OFFSET_LEFT, fir_cfg->dc_offset_left);
	dai_dmic_write(dmic, base + DC_OFFSET_RIGHT, fir_cfg->dc_offset_right);
	dai_dmic_write(dmic, base + OUT_GAIN_LEFT, fir_cfg->out_gain_left);
	dai_dmic_write(dmic, base + OUT_GAIN_RIGHT, fir_cfg->out_gain_right);

	dmic->gain_left = fir_cfg->out_gain_left;
	dmic->gain_right = fir_cfg->out_gain_right;
}

int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cfg)
{
	const struct nhlt_pdm_ctrl_cfg *pdm_cfg;
	struct nhlt_dmic_channel_ctrl_mask *dmic_cfg;

	uint32_t channel_ctrl_mask;
	uint32_t pdm_ctrl_mask;
	uint32_t pdm_base;
	int pdm_idx;
	uint32_t val;
	uint32_t outcontrol;
	const uint8_t *p = bespoke_cfg;
	int num_fifos;
	int num_pdm;
	int n;
	int ret;

	const uint32_t *fir_coeffs;

	/* Array of pointers to pdm coefficient data. Used to reuse coefficient from another pdm. */
	const uint32_t *pdm_coeff_ptr[DMIC_HW_CONTROLLERS_MAX] = { 0 };

	if (dmic->dai_config_params.dai_index >= DMIC_HW_FIFOS_MAX) {
		LOG_ERR("dmic_set_config_nhlt(): illegal DAI index %d",
			 dmic->dai_config_params.dai_index);
		return -EINVAL;
	}

	/* Skip not used headers */
	p += sizeof(struct nhlt_dmic_gateway_attributes);
	p += sizeof(struct nhlt_dmic_ts_group);
	p += sizeof(struct nhlt_dmic_global_config);

	/* Channel_ctlr_mask bits indicate the FIFOs enabled*/
	dmic_cfg = (struct nhlt_dmic_channel_ctrl_mask *)p;
	channel_ctrl_mask = dmic_cfg->channel_ctrl_mask;
	num_fifos = POPCOUNT(channel_ctrl_mask); /* Count set bits */
	p += sizeof(struct nhlt_dmic_channel_ctrl_mask);
	LOG_DBG("dmic_set_config_nhlt(): channel_ctrl_mask = %d", channel_ctrl_mask);

	/* Configure clock source */
	ret = dai_dmic_set_clock(dmic, dmic_cfg->clock_source);
	if (ret)
		return ret;

	/* Get OUTCONTROLx configuration */
	if (num_fifos < 1 || num_fifos > DMIC_HW_FIFOS_MAX) {
		LOG_ERR("dmic_set_config_nhlt(): illegal number of FIFOs %d", num_fifos);
		return -EINVAL;
	}

	for (n = 0; n < DMIC_HW_FIFOS_MAX; n++) {
		if (!(channel_ctrl_mask & (1 << n)))
			continue;

		val = *(uint32_t *)p;
		ret = print_outcontrol(val);
		if (ret) {
			return ret;
		}

		if (dmic->dai_config_params.dai_index == n) {
			/* Write the FIFO control registers. The clear/set of bits is the same for
			 * all DMIC_HW_VERSION
			 */
			/* Clear TIE, SIP, FCI, set FINIT, the rest of bits as such */
			outcontrol = (val & ~(OUTCONTROL_TIE | OUTCONTROL_SIP | OUTCONTROL_FCI)) |
				OUTCONTROL_FINIT;

			dai_dmic_write(dmic, dmic->dai_config_params.dai_index *
				       PDM_CHANNEL_REGS_SIZE + OUTCONTROL, outcontrol);

			LOG_INF("OUTCONTROL%d = %08x", dmic->dai_config_params.dai_index,
				outcontrol);

			/* Pass 2^BFTH to plat_data fifo depth. It will be used later in DMA
			 * configuration
			 */
			val = FIELD_GET(OUTCONTROL_BFTH, outcontrol);
			dmic->fifo.depth = 1 << val;
		}

		p += sizeof(uint32_t);
	}

	/* Get PDMx registers */
	pdm_ctrl_mask = ((const struct nhlt_pdm_ctrl_mask *)p)->pdm_ctrl_mask;
	num_pdm = POPCOUNT(pdm_ctrl_mask); /* Count set bits */
	p += sizeof(struct nhlt_pdm_ctrl_mask);
	LOG_DBG("dmic_set_config_nhlt(): pdm_ctrl_mask = %d", pdm_ctrl_mask);
	if (num_pdm < 1 || num_pdm > CONFIG_DAI_DMIC_HW_CONTROLLERS) {
		LOG_ERR("dmic_set_config_nhlt(): illegal number of PDMs %d", num_pdm);
		return -EINVAL;
	}

	pdm_cfg = (const struct nhlt_pdm_ctrl_cfg *)p;

	for (pdm_idx = 0; pdm_idx < CONFIG_DAI_DMIC_HW_CONTROLLERS; pdm_idx++) {
		pdm_base = dmic_base[pdm_idx];

		if (!(pdm_ctrl_mask & (1 << pdm_idx))) {
			/* Set MIC_MUTE bit to unused PDM */
			dai_dmic_write(dmic, pdm_base + CIC_CONTROL, CIC_CONTROL_MIC_MUTE);
			continue;
		}

		LOG_DBG("PDM%d", pdm_idx);

		/* Get CIC configuration */
		if (dai_dmic_global.active_fifos_mask == 0) {
			print_pdm_ctrl(pdm_cfg);

			val = pdm_cfg->cic_control;
			print_cic_control(val);

			/* Clear CIC_START_A and CIC_START_B */
			val = (val & ~(CIC_CONTROL_CIC_START_A | CIC_CONTROL_CIC_START_B));
			dai_dmic_write(dmic, pdm_base + CIC_CONTROL, val);
			LOG_DBG("dmic_set_config_nhlt(): CIC_CONTROL = %08x", val);

			/* Use CIC_CONFIG as such */
			val = pdm_cfg->cic_config;
			dai_dmic_write(dmic, pdm_base + CIC_CONFIG, val);

			/* Clear PDM_EN_A and PDM_EN_B */
			val = pdm_cfg->mic_control;
			val &= ~(MIC_CONTROL_PDM_EN_A | MIC_CONTROL_PDM_EN_B);
			dai_dmic_write(dmic, pdm_base + MIC_CONTROL, val);
			LOG_DBG("dmic_set_config_nhlt(): MIC_CONTROL = %08x", val);
		}

		configure_fir(dmic, pdm_base +
			      FIR_CHANNEL_REGS_SIZE * dmic->dai_config_params.dai_index,
			      &pdm_cfg->fir_config[dmic->dai_config_params.dai_index]);


		/* Configure fir coefficients */

		/* Check if FIR coeffs should be reused */
		if (pdm_cfg->reuse_fir_from_pdm == 0) {
			/* get ptr, where FIR coeffs starts */
			fir_coeffs = pdm_cfg->fir_coeffs;

			/* and save it for future pdms reference */
			pdm_coeff_ptr[pdm_idx] = fir_coeffs;
		} else {
			if (pdm_cfg->reuse_fir_from_pdm > pdm_idx) {
				LOG_ERR("invalid reuse fir index %u", pdm_cfg->reuse_fir_from_pdm);
				return -EINVAL;
			}

			/* get FIR coeffs from another pdm */
			fir_coeffs = pdm_coeff_ptr[pdm_cfg->reuse_fir_from_pdm - 1];

			if (!fir_coeffs) {
				LOG_ERR("unable to reuse fir from %u", pdm_cfg->reuse_fir_from_pdm);
				return -EINVAL;
			}
		}

		fir_coeffs = dai_dmic_configure_coeff(dmic, pdm_cfg, pdm_base, fir_coeffs);

		/* Update pdm_cfg ptr for next PDM Ctrl. */
		if (pdm_cfg->reuse_fir_from_pdm) {
			/* fir_coeffs array is empty if reusing previous coeffs */
			pdm_cfg = (const struct nhlt_pdm_ctrl_cfg *)&pdm_cfg->fir_coeffs;
		} else {
			pdm_cfg = (const struct nhlt_pdm_ctrl_cfg *)fir_coeffs;
		}
	}

#ifdef CONFIG_SOC_SERIES_INTEL_ADSP_ACE
	ret = dai_nhlt_dmic_dai_params_get(dmic, dmic_cfg->clock_source);
#else
	ret = dai_nhlt_dmic_dai_params_get(dmic);
#endif
	if (ret)
		return ret;

	LOG_INF("dmic_set_config_nhlt(): enable0 %u, enable1 %u",
		dmic->enable[0], dmic->enable[1]);
	return 0;
}
