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

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

#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <zephyr/kernel.h>
#include <zephyr/spinlock.h>
#include <zephyr/devicetree.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>

#include <zephyr/drivers/dai.h>
#include <zephyr/irq.h>

#include "dmic.h"

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

/* global data shared between all dmic instances */
struct dai_dmic_global_shared dai_dmic_global;

/* Helper macro to read 64-bit data using two 32-bit data read */
#define sys_read64(addr)    (((uint64_t)(sys_read32(addr + 4)) << 32) | \
			     sys_read32(addr))

int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *spec_config);

/* Exponent function for small values of x. This function calculates
 * fairly accurately exponent for x in range -2.0 .. +2.0. The iteration
 * uses first 11 terms of Taylor series approximation for exponent
 * function. With the current scaling the numerator just remains under
 * 64 bits with the 11 terms.
 *
 * See https://en.wikipedia.org/wiki/Exponential_function#Computation
 *
 * The input is Q3.29
 * The output is Q9.23
 */
static int32_t exp_small_fixed(int32_t x)
{
	int64_t p;
	int64_t num = Q_SHIFT_RND(x, 29, 23);
	int32_t y = (int32_t)num;
	int32_t den = 1;
	int32_t inc;
	int k;

	/* Numerator is x^k, denominator is k! */
	for (k = 2; k < 12; k++) {
		p = num * x; /* Q9.23 x Q3.29 -> Q12.52 */
		num = Q_SHIFT_RND(p, 52, 23);
		den = den * k;
		inc = (int32_t)(num / den);
		y += inc;
	}

	return y + ONE_Q23;
}

static int32_t exp_fixed(int32_t x)
{
	int32_t xs;
	int32_t y;
	int32_t z;
	int i;
	int n = 0;

	if (x < Q_CONVERT_FLOAT(-11.5, 27))
		return 0;

	if (x > Q_CONVERT_FLOAT(7.6245, 27))
		return INT32_MAX;

	/* x is Q5.27 */
	xs = x;
	while (xs >= TWO_Q27 || xs <= MINUS_TWO_Q27) {
		xs >>= 1;
		n++;
	}

	/* exp_small_fixed() input is Q3.29, while x1 is Q5.27
	 * exp_small_fixed() output is Q9.23, while z is Q12.20
	 */
	z = Q_SHIFT_RND(exp_small_fixed(Q_SHIFT_LEFT(xs, 27, 29)), 23, 20);
	y = ONE_Q20;
	for (i = 0; i < (1 << n); i++)
		y = (int32_t)Q_MULTSR_32X32((int64_t)y, z, 20, 20, 20);

	return y;
}

static int32_t db2lin_fixed(int32_t db)
{
	int32_t arg;

	if (db < Q_CONVERT_FLOAT(-100.0, 24))
		return 0;

	/* Q8.24 x Q5.27, result needs to be Q5.27 */
	arg = (int32_t)Q_MULTSR_32X32((int64_t)db, LOG10_DIV20_Q27, 24, 27, 27);
	return exp_fixed(arg);
}

static void dai_dmic_update_bits(const struct dai_intel_dmic *dmic,
				 uint32_t reg, uint32_t mask, uint32_t val)
{
	uint32_t dest = dmic->reg_base + reg;

	LOG_INF("%s base %x, reg %x, mask %x, value %x", __func__,
			dmic->reg_base, reg, mask, val);

	sys_write32((sys_read32(dest) & (~mask)) | (val & mask), dest);
}

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);
}

#if CONFIG_DAI_DMIC_HAS_OWNERSHIP
static inline void dai_dmic_claim_ownership(const struct dai_intel_dmic *dmic)
{
	/* DMIC Owner Select to DSP */
	sys_write32(sys_read32(dmic->shim_base + DMICLCTL_OFFSET) |
			DMICLCTL_OSEL(0x3), dmic->shim_base + DMICLCTL_OFFSET);
}

static inline void dai_dmic_release_ownership(const struct dai_intel_dmic *dmic)
{
	/* DMIC Owner Select back to Host CPU + DSP */
	sys_write32(sys_read32(dmic->shim_base + DMICLCTL_OFFSET) &
			~DMICLCTL_OSEL(0x0), dmic->shim_base + DMICLCTL_OFFSET);
}

#else /* CONFIG_DAI_DMIC_HAS_OWNERSHIP */

static inline void dai_dmic_claim_ownership(const struct dai_intel_dmic *dmic) {}
static inline void dai_dmic_release_ownership(const struct dai_intel_dmic *dmic) {}

#endif /* CONFIG_DAI_DMIC_HAS_OWNERSHIP */

static inline uint32_t dai_dmic_base(const struct dai_intel_dmic *dmic)
{
#ifdef CONFIG_SOC_INTEL_ACE20_LNL
	return dmic->hdamldmic_base;
#else
	return dmic->shim_base;
#endif
}

#if CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC
static inline void dai_dmic_set_sync_period(uint32_t period, const struct dai_intel_dmic *dmic)
{
	uint32_t val = CONFIG_DAI_DMIC_HW_IOCLK / period - 1;
	uint32_t base = dai_dmic_base(dmic);
	/* DMIC Change sync period */
#ifdef CONFIG_SOC_INTEL_ACE20_LNL
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPRD(val),
		    base + DMICSYNC_OFFSET);
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPU,
		    base + DMICSYNC_OFFSET);
	while (sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_SYNCPU) {
		k_sleep(K_USEC(100));
	}
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
		    base + DMICSYNC_OFFSET);
#else /* All other CAVS and ACE platforms */
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPRD(val),
		    base + DMICSYNC_OFFSET);
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
		    base + DMICSYNC_OFFSET);
#endif
}

static inline void dai_dmic_clear_sync_period(const struct dai_intel_dmic *dmic)
{
	uint32_t base = dai_dmic_base(dmic);
	/* DMIC Clean sync period */
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) & ~DMICSYNC_SYNCPRD(0x0000),
			base + DMICSYNC_OFFSET);
	sys_write32(sys_read32(base + DMICSYNC_OFFSET) & ~DMICSYNC_CMDSYNC,
			base + DMICSYNC_OFFSET);
}

/* Preparing for command synchronization on multiple link segments */
static inline void dai_dmic_sync_prepare(const struct dai_intel_dmic *dmic)
{
	uint32_t base = dai_dmic_base(dmic);

	sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
		    base + DMICSYNC_OFFSET);
}

/* Trigering synchronization of command execution */
static void dmic_sync_trigger(const struct dai_intel_dmic *dmic)
{
	uint32_t base = dai_dmic_base(dmic);

	__ASSERT_NO_MSG((sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_CMDSYNC) != 0);

	sys_write32(sys_read32(base + DMICSYNC_OFFSET) |
		    DMICSYNC_SYNCGO, base + DMICSYNC_OFFSET);
	/* waiting for CMDSYNC bit clearing */
	while (sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_CMDSYNC) {
		k_sleep(K_USEC(100));
	}
}

#else /* CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC */

static inline void dai_dmic_set_sync_period(uint32_t period, const struct dai_intel_dmic *dmic) {}
static inline void dai_dmic_clear_sync_period(const struct dai_intel_dmic *dmic) {}
static inline void dai_dmic_sync_prepare(const struct dai_intel_dmic *dmic) {}
static void dmic_sync_trigger(const struct dai_intel_dmic *dmic) {}

#endif /* CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC */

static void dai_dmic_stop_fifo_packers(struct dai_intel_dmic *dmic,
					int fifo_index)
{
	/* Stop FIFO packers and set FIFO initialize bits */
	switch (fifo_index) {
	case 0:
		dai_dmic_update_bits(dmic, OUTCONTROL0,
				OUTCONTROL0_SIP_BIT | OUTCONTROL0_FINIT_BIT,
				OUTCONTROL0_FINIT_BIT);
		break;
	case 1:
		dai_dmic_update_bits(dmic, OUTCONTROL1,
				OUTCONTROL1_SIP_BIT | OUTCONTROL1_FINIT_BIT,
				OUTCONTROL1_FINIT_BIT);
		break;
	}
}

/* On DMIC IRQ event trace the status register that contains the status and
 * error bit fields.
 */
static void dai_dmic_irq_handler(const void *data)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *) data;
	uint32_t val0;
	uint32_t val1;

	/* Trace OUTSTAT0 register */
	val0 = dai_dmic_read(dmic, OUTSTAT0);
	val1 = dai_dmic_read(dmic, OUTSTAT1);
	LOG_DBG("dmic_irq_handler(), OUTSTAT0 = 0x%x, OUTSTAT1 = 0x%x", val0, val1);

	if (val0 & OUTSTAT0_ROR_BIT) {
		LOG_ERR("dmic_irq_handler(): full fifo A or PDM overrun");
		dai_dmic_write(dmic, OUTSTAT0, val0);
		dai_dmic_stop_fifo_packers(dmic, 0);
	}

	if (val1 & OUTSTAT1_ROR_BIT) {
		LOG_ERR("dmic_irq_handler(): full fifo B or PDM overrun");
		dai_dmic_write(dmic, OUTSTAT1, val1);
		dai_dmic_stop_fifo_packers(dmic, 1);
	}
}

static inline void dai_dmic_dis_clk_gating(const struct dai_intel_dmic *dmic)
{
	/* Disable DMIC clock gating */
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	sys_write32((sys_read32(dmic->vshim_base + DMICLCTL_OFFSET) | DMIC_DCGD),
		    dmic->vshim_base + DMICLCTL_OFFSET);
#else
	sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) | DMIC_DCGD),
		    dmic->shim_base + DMICLCTL_OFFSET);
#endif
}

static inline void dai_dmic_en_clk_gating(const struct dai_intel_dmic *dmic)
{
	/* Enable DMIC clock gating */
#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	sys_write32((sys_read32(dmic->vshim_base + DMICLCTL_OFFSET) & ~DMIC_DCGD),
		    dmic->vshim_base + DMICLCTL_OFFSET);
#else
	sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & ~DMIC_DCGD),
		    dmic->shim_base + DMICLCTL_OFFSET);
#endif

}

static inline void dai_dmic_program_channel_map(const struct dai_intel_dmic *dmic,
						const struct dai_config *cfg,
						uint32_t index)
{
#ifdef CONFIG_SOC_INTEL_ACE20_LNL
	uint16_t pcmsycm = cfg->link_config;
	uint32_t reg_add = dmic->shim_base + DMICXPCMSyCM_OFFSET + 0x0004*index;

	sys_write16(pcmsycm, reg_add);
#else
	ARG_UNUSED(dmic);
	ARG_UNUSED(cfg);
	ARG_UNUSED(index);
#endif /* defined(CONFIG_SOC_INTEL_ACE20_LNL) */
}

static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic)
{
	uint32_t base = dai_dmic_base(dmic);
	/* Enable DMIC power */
	sys_write32((sys_read32(base + DMICLCTL_OFFSET) | DMICLCTL_SPA),
			base + DMICLCTL_OFFSET);

#ifdef CONFIG_SOC_INTEL_ACE20_LNL /* Ace 2.0 */
	while (!(sys_read32(base + DMICLCTL_OFFSET) & DMICLCTL_CPA)) {
		k_sleep(K_USEC(100));
	}
#endif
}

static inline void dai_dmic_dis_power(const struct dai_intel_dmic *dmic)
{
	uint32_t base = dai_dmic_base(dmic);
	/* Disable DMIC power */
	sys_write32((sys_read32(base + DMICLCTL_OFFSET) & (~DMICLCTL_SPA)),
		     base + DMICLCTL_OFFSET);
}

static int dai_dmic_probe(struct dai_intel_dmic *dmic)
{
	LOG_INF("dmic_probe()");

	/* Set state, note there is no playback direction support */
	dmic->state = DAI_STATE_NOT_READY;

	/* Enable DMIC power */
	dai_dmic_en_power(dmic);

	/* Disable dynamic clock gating for dmic before touching any reg */
	dai_dmic_dis_clk_gating(dmic);

	/* DMIC Change sync period */
	dai_dmic_set_sync_period(CONFIG_DAI_DMIC_PLATFORM_SYNC_PERIOD, dmic);

	/* DMIC Owner Select to DSP */
	dai_dmic_claim_ownership(dmic);

	irq_enable(dmic->irq);

	return 0;
}

static int dai_dmic_remove(struct dai_intel_dmic *dmic)
{
	uint32_t active_fifos_mask = dai_dmic_global.active_fifos_mask;
	uint32_t pause_mask = dai_dmic_global.pause_mask;

	LOG_INF("dmic_remove()");

	irq_disable(dmic->irq);

	LOG_INF("dmic_remove(), dmic_active_fifos_mask = 0x%x, dmic_pause_mask = 0x%x",
		active_fifos_mask, pause_mask);

	/* The next end tasks must be passed if another DAI FIFO still runs.
	 * Note: dai_put() function that calls remove() applies the spinlock
	 * so it is not needed here to protect access to mask bits.
	 */
	if (active_fifos_mask || pause_mask)
		return 0;

	/* Disable DMIC clock and power */
	dai_dmic_en_clk_gating(dmic);
	dai_dmic_dis_power(dmic);

	/* DMIC Clean sync period */
	dai_dmic_clear_sync_period(dmic);

	/* DMIC Owner Select back to Host CPU + DSP */
	dai_dmic_release_ownership(dmic);

	return 0;
}

static int dai_dmic_timestamp_config(const struct device *dev, struct dai_ts_cfg *cfg)
{
	cfg->walclk_rate = CONFIG_DAI_DMIC_HW_IOCLK;

	return 0;
}

static int dai_timestamp_dmic_start(const struct device *dev, struct dai_ts_cfg *cfg)
{
	uint32_t addr = TS_DMIC_LOCAL_TSCTRL;
	uint32_t cdmas;

	/* Set DMIC timestamp registers */

	/* First point CDMAS to GPDMA channel that is used by DMIC
	 * also clear NTK to be sure there is no old timestamp.
	 */
	cdmas = TS_LOCAL_TSCTRL_CDMAS(cfg->dma_chan_index +
		cfg->dma_chan_count * cfg->dma_id);
	sys_write32(TS_LOCAL_TSCTRL_NTK_BIT | cdmas, addr);

	/* Request on demand timestamp */
	sys_write32(TS_LOCAL_TSCTRL_ODTS_BIT | cdmas, addr);

	return 0;
}

static int dai_timestamp_dmic_stop(const struct device *dev, struct dai_ts_cfg *cfg)
{
	/* Clear NTK and write zero to CDMAS */
	sys_write32(TS_LOCAL_TSCTRL_NTK_BIT,
		    TS_DMIC_LOCAL_TSCTRL);
	return 0;
}

static int dai_timestamp_dmic_get(const struct device *dev, struct dai_ts_cfg *cfg,
				  struct dai_ts_data *tsd)
{
	/* Read DMIC timestamp registers */
	uint32_t tsctrl = TS_DMIC_LOCAL_TSCTRL;
	uint32_t ntk;

	/* Read SSP timestamp registers */
	ntk = sys_read32(tsctrl) & TS_LOCAL_TSCTRL_NTK_BIT;
	if (!ntk)
		goto out;

	/* NTK was set, get wall clock */
	tsd->walclk = sys_read64(TS_DMIC_LOCAL_WALCLK);

	/* Sample */
	tsd->sample = sys_read64(TS_DMIC_LOCAL_SAMPLE);

	/* Clear NTK to enable successive timestamps */
	sys_write32(TS_LOCAL_TSCTRL_NTK_BIT, tsctrl);

out:
	tsd->walclk_rate = cfg->walclk_rate;
	if (!ntk)
		return -ENODATA;

	return 0;
}

/* this ramps volume changes over time */
static void dai_dmic_gain_ramp(struct dai_intel_dmic *dmic)
{
	k_spinlock_key_t key;
	int32_t gval;
	uint32_t val;
	int i;

	/* Currently there's no DMIC HW internal mutings and wait times
	 * applied into this start sequence. It can be implemented here if
	 * start of audio capture would contain clicks and/or noise and it
	 * is not suppressed by gain ramp somewhere in the capture pipe.
	 */
	LOG_DBG("DMIC gain ramp");

	/*
	 * At run-time dmic->gain is only changed in this function, and this
	 * function runs in the pipeline task context, so it cannot run
	 * concurrently on multiple cores, since there's always only one
	 * task associated with each DAI, so we don't need to hold the lock to
	 * read the value here.
	 */
	if (dmic->gain == DMIC_HW_FIR_GAIN_MAX << 11)
		return;

	key = k_spin_lock(&dmic->lock);

	/* Increment gain with logarithmic step.
	 * Gain is Q2.30 and gain modifier is Q12.20.
	 */
	dmic->startcount++;
	dmic->gain = q_multsr_sat_32x32(dmic->gain, dmic->gain_coef, Q_SHIFT_GAIN_X_GAIN_COEF);

	/* Gain is stored as Q2.30, while HW register is Q1.19 so shift
	 * the value right by 11.
	 */
	gval = dmic->gain >> 11;

	/* Note that DMIC gain value zero has a special purpose. Value zero
	 * sets gain bypass mode in HW. Zero value will be applied after ramp
	 * is complete. It is because exact 1.0 gain is not possible with Q1.19.
	 */
	if (gval > DMIC_HW_FIR_GAIN_MAX) {
		gval = 0;
		dmic->gain = DMIC_HW_FIR_GAIN_MAX << 11;
	}

	/* Write gain to registers */
	for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
		if (!dmic->enable[i])
			continue;

		if (dmic->startcount == DMIC_UNMUTE_CIC)
			dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
					     CIC_CONTROL_MIC_MUTE_BIT, 0);

		if (dmic->startcount == DMIC_UNMUTE_FIR) {
			switch (dmic->dai_config_params.dai_index) {
			case 0:
				dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_A,
						     FIR_CONTROL_A_MUTE_BIT, 0);
				break;
			case 1:
				dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_B,
						     FIR_CONTROL_B_MUTE_BIT, 0);
				break;
			}
		}
		switch (dmic->dai_config_params.dai_index) {
		case 0:
			val = OUT_GAIN_LEFT_A_GAIN(gval);
			dai_dmic_write(dmic, base[i] + OUT_GAIN_LEFT_A, val);
			dai_dmic_write(dmic, base[i] + OUT_GAIN_RIGHT_A, val);
			break;
		case 1:
			val = OUT_GAIN_LEFT_B_GAIN(gval);
			dai_dmic_write(dmic, base[i] + OUT_GAIN_LEFT_B, val);
			dai_dmic_write(dmic, base[i] + OUT_GAIN_RIGHT_B, val);
			break;
		}
	}

	k_spin_unlock(&dmic->lock, key);
}

static void dai_dmic_start(struct dai_intel_dmic *dmic)
{
	k_spinlock_key_t key;
	int i;
	int mic_a;
	int mic_b;
	int fir_a;
	int fir_b;

	/* enable port */
	key = k_spin_lock(&dmic->lock);
	LOG_DBG("dmic_start()");
	dmic->startcount = 0;

	/* Compute unmute ramp gain update coefficient. */
	dmic->gain_coef = db2lin_fixed(LOGRAMP_CONST_TERM / dmic->unmute_time_ms);

	/* Initial gain value, convert Q12.20 to Q2.30 */
	dmic->gain = Q_SHIFT_LEFT(db2lin_fixed(LOGRAMP_START_DB), 20, 30);

	dai_dmic_sync_prepare(dmic);

	switch (dmic->dai_config_params.dai_index) {
	case 0:
		LOG_INF("dmic_start(), dmic->fifo_a");
		/*  Clear FIFO A initialize, Enable interrupts to DSP,
		 *  Start FIFO A packer.
		 */
		dai_dmic_update_bits(
				dmic,
				OUTCONTROL0,
				OUTCONTROL0_FINIT_BIT | OUTCONTROL0_SIP_BIT,
				OUTCONTROL0_SIP_BIT);
		break;
	case 1:
		LOG_INF("dmic_start(), dmic->fifo_b");
		/*  Clear FIFO B initialize, Enable interrupts to DSP,
		 *  Start FIFO B packer.
		 */
		dai_dmic_update_bits(dmic, OUTCONTROL1,
				     OUTCONTROL1_FINIT_BIT | OUTCONTROL1_SIP_BIT,
				     OUTCONTROL1_SIP_BIT);
	}

	for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
#ifdef CONFIG_SOC_SERIES_INTEL_ACE
		dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
				     CIC_CONTROL_SOFT_RESET_BIT, 0);

		LOG_INF("dmic_start(), cic 0x%08x",
			dai_dmic_read(dmic, base[i] + CIC_CONTROL));
#endif

		mic_a = dmic->enable[i] & 1;
		mic_b = (dmic->enable[i] & 2) >> 1;
		fir_a = (dmic->enable[i] > 0) ? 1 : 0;
		fir_b = (dmic->enable[i] > 0) ? 1 : 0;
		LOG_INF("dmic_start(), pdm%d mic_a = %u, mic_b = %u", i, mic_a, mic_b);

		/* If both microphones are needed start them simultaneously
		 * to start them in sync. The reset may be cleared for another
		 * FIFO already. If only one mic, start them independently.
		 * This makes sure we do not clear start/en for another DAI.
		 */
		if (mic_a && mic_b) {
			dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
					     CIC_CONTROL_CIC_START_A_BIT |
					     CIC_CONTROL_CIC_START_B_BIT,
					     CIC_CONTROL_CIC_START_A(1) |
					     CIC_CONTROL_CIC_START_B(1));
			dai_dmic_update_bits(dmic, base[i] + MIC_CONTROL,
					     MIC_CONTROL_PDM_EN_A_BIT |
					     MIC_CONTROL_PDM_EN_B_BIT,
					     MIC_CONTROL_PDM_EN_A(1) |
					     MIC_CONTROL_PDM_EN_B(1));
		} else if (mic_a) {
			dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
					     CIC_CONTROL_CIC_START_A_BIT,
					     CIC_CONTROL_CIC_START_A(1));
			dai_dmic_update_bits(dmic, base[i] + MIC_CONTROL,
					     MIC_CONTROL_PDM_EN_A_BIT,
					     MIC_CONTROL_PDM_EN_A(1));
		} else if (mic_b) {
			dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
					     CIC_CONTROL_CIC_START_B_BIT,
					     CIC_CONTROL_CIC_START_B(1));
			dai_dmic_update_bits(dmic, base[i] + MIC_CONTROL,
					     MIC_CONTROL_PDM_EN_B_BIT,
					     MIC_CONTROL_PDM_EN_B(1));
		}

		switch (dmic->dai_config_params.dai_index) {
		case 0:
			dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_A,
					     FIR_CONTROL_A_START_BIT,
					     FIR_CONTROL_A_START(fir_a));
			break;
		case 1:
			dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_B,
					     FIR_CONTROL_B_START_BIT,
					     FIR_CONTROL_B_START(fir_b));
			break;
		}
	}

#ifndef CONFIG_SOC_SERIES_INTEL_ACE
	/* Clear soft reset for all/used PDM controllers. This should
	 * start capture in sync.
	 */
	for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
		dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
				     CIC_CONTROL_SOFT_RESET_BIT, 0);

		LOG_INF("dmic_start(), cic 0x%08x",
			dai_dmic_read(dmic, base[i] + CIC_CONTROL));
	}
#endif

	/* Set bit dai->index */
	dai_dmic_global.active_fifos_mask |= BIT(dmic->dai_config_params.dai_index);
	dai_dmic_global.pause_mask &= ~BIT(dmic->dai_config_params.dai_index);

	dmic->state = DAI_STATE_RUNNING;
	k_spin_unlock(&dmic->lock, key);

	dmic_sync_trigger(dmic);

	LOG_INF("dmic_start(), dmic_active_fifos_mask = 0x%x",
		dai_dmic_global.active_fifos_mask);
}

static void dai_dmic_stop(struct dai_intel_dmic *dmic, bool stop_is_pause)
{
	k_spinlock_key_t key;
	int i;

	LOG_DBG("dmic_stop()");
	key = k_spin_lock(&dmic->lock);

	dai_dmic_stop_fifo_packers(dmic, dmic->dai_config_params.dai_index);

	/* Set soft reset and mute on for all PDM controllers. */
	LOG_INF("dmic_stop(), dmic_active_fifos_mask = 0x%x",
			dai_dmic_global.active_fifos_mask);

	/* Clear bit dmic->dai_config_params.dai_index for active FIFO.
	 * If stop for pause, set pause mask bit.
	 * If stop is not for pausing, it is safe to clear the pause bit.
	 */
	dai_dmic_global.active_fifos_mask &= ~BIT(dmic->dai_config_params.dai_index);
	if (stop_is_pause)
		dai_dmic_global.pause_mask |= BIT(dmic->dai_config_params.dai_index);
	else
		dai_dmic_global.pause_mask &= ~BIT(dmic->dai_config_params.dai_index);

	for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
		/* Don't stop CIC yet if one FIFO remains active */
		if (dai_dmic_global.active_fifos_mask == 0) {
			dai_dmic_update_bits(dmic, base[i] + CIC_CONTROL,
					     CIC_CONTROL_SOFT_RESET_BIT |
					     CIC_CONTROL_MIC_MUTE_BIT,
					     CIC_CONTROL_SOFT_RESET_BIT |
					     CIC_CONTROL_MIC_MUTE_BIT);
		}
		switch (dmic->dai_config_params.dai_index) {
		case 0:
			dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_A,
					     FIR_CONTROL_A_MUTE_BIT,
					     FIR_CONTROL_A_MUTE_BIT);
			break;
		case 1:
			dai_dmic_update_bits(dmic, base[i] + FIR_CONTROL_B,
					     FIR_CONTROL_B_MUTE_BIT,
					     FIR_CONTROL_B_MUTE_BIT);
			break;
		}
	}

	k_spin_unlock(&dmic->lock, key);
}

const struct dai_properties *dai_dmic_get_properties(const struct device *dev,
						     enum dai_dir dir,
						     int stream_id)
{
	const struct dai_intel_dmic *dmic = (const struct dai_intel_dmic *)dev->data;
	struct dai_properties *prop = (struct dai_properties *)dev->config;

	prop->fifo_address = dmic->fifo.offset;
	prop->fifo_depth = dmic->fifo.depth;
	prop->dma_hs_id = dmic->fifo.handshake;
	prop->reg_init_delay = 0;

	return prop;
}

static int dai_dmic_trigger(const struct device *dev, enum dai_dir dir,
			    enum dai_trigger_cmd cmd)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;

	LOG_DBG("dmic_trigger()");

	if (dir != DAI_DIR_RX) {
		LOG_ERR("dmic_trigger(): direction != DAI_DIR_RX");
		return -EINVAL;
	}

	switch (cmd) {
	case DAI_TRIGGER_START:
		if (dmic->state == DAI_STATE_PAUSED ||
		    dmic->state == DAI_STATE_PRE_RUNNING) {
			dai_dmic_start(dmic);
			dmic->state = DAI_STATE_RUNNING;
		} else {
			LOG_ERR("dmic_trigger(): state is not prepare or paused, dmic->state = %u",
				dmic->state);
		}
		break;
	case DAI_TRIGGER_STOP:
		dai_dmic_stop(dmic, false);
		dmic->state = DAI_STATE_PRE_RUNNING;
		break;
	case DAI_TRIGGER_PAUSE:
		dai_dmic_stop(dmic, true);
		dmic->state = DAI_STATE_PAUSED;
		break;
	case DAI_TRIGGER_COPY:
		dai_dmic_gain_ramp(dmic);
		break;
	default:
		break;
	}

	return 0;
}

static int dai_dmic_get_config(const struct device *dev, struct dai_config *cfg, enum dai_dir dir)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;

	if (dir != DAI_DIR_RX) {
		return -EINVAL;
	}

	if (!cfg) {
		return -EINVAL;
	}

	*cfg = dmic->dai_config_params;

	return 0;
}

static int dai_dmic_set_config(const struct device *dev,
		const struct dai_config *cfg, const void *bespoke_cfg)

{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;
	int ret = 0;
	int di = dmic->dai_config_params.dai_index;
	k_spinlock_key_t key;

	LOG_INF("dmic_set_config()");

	if (di >= CONFIG_DAI_DMIC_HW_FIFOS) {
		LOG_ERR("dmic_set_config(): DAI index exceeds number of FIFOs");
		return -EINVAL;
	}

	if (!bespoke_cfg) {
		LOG_ERR("dmic_set_config(): NULL config");
		return -EINVAL;
	}

	dai_dmic_program_channel_map(dmic, cfg, di);

	key = k_spin_lock(&dmic->lock);

#if CONFIG_DAI_INTEL_DMIC_TPLG_PARAMS
#error DMIC TPLG is not yet implemented

#elif CONFIG_DAI_INTEL_DMIC_NHLT
	ret = dai_dmic_set_config_nhlt(dmic, bespoke_cfg);

	/* There's no unmute ramp duration in blob, so the default rate dependent is used. */
	dmic->unmute_time_ms = dmic_get_unmute_ramp_from_samplerate(dmic->dai_config_params.rate);
#else
#error No DMIC config selected
#endif

	if (ret < 0) {
		LOG_ERR("dmic_set_config(): Failed to set the requested configuration.");
		goto out;
	}

	dmic->state = DAI_STATE_PRE_RUNNING;

out:
	k_spin_unlock(&dmic->lock, key);
	return ret;
}

static int dai_dmic_probe_wrapper(const struct device *dev)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;
	k_spinlock_key_t key;
	int ret = 0;

	key = k_spin_lock(&dmic->lock);

	if (dmic->sref == 0) {
		ret = dai_dmic_probe(dmic);
	}

	if (!ret) {
		dmic->sref++;
	}

	k_spin_unlock(&dmic->lock, key);

	return ret;
}

static int dai_dmic_remove_wrapper(const struct device *dev)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;
	k_spinlock_key_t key;
	int ret = 0;

	key = k_spin_lock(&dmic->lock);

	if (--dmic->sref == 0) {
		ret = dai_dmic_remove(dmic);
	}

	k_spin_unlock(&dmic->lock, key);

	return ret;
}

static int dmic_pm_action(const struct device *dev, enum pm_device_action action)
{
	switch (action) {
	case PM_DEVICE_ACTION_SUSPEND:
		dai_dmic_remove_wrapper(dev);
		break;
	case PM_DEVICE_ACTION_RESUME:
		dai_dmic_probe_wrapper(dev);
		break;
	case PM_DEVICE_ACTION_TURN_OFF:
	case PM_DEVICE_ACTION_TURN_ON:
		/* All device pm is handled during resume and suspend */
		break;
	default:
		return -ENOTSUP;
	}

	return 0;
}

const struct dai_driver_api dai_dmic_ops = {
	.probe			= pm_device_runtime_get,
	.remove			= pm_device_runtime_put,
	.config_set		= dai_dmic_set_config,
	.config_get		= dai_dmic_get_config,
	.get_properties		= dai_dmic_get_properties,
	.trigger		= dai_dmic_trigger,
	.ts_config		= dai_dmic_timestamp_config,
	.ts_start		= dai_timestamp_dmic_start,
	.ts_stop		= dai_timestamp_dmic_stop,
	.ts_get			= dai_timestamp_dmic_get
};

static int dai_dmic_initialize_device(const struct device *dev)
{
	IRQ_CONNECT(
		DT_INST_IRQN(0),
		IRQ_DEFAULT_PRIORITY,
		dai_dmic_irq_handler,
		DEVICE_DT_INST_GET(0),
		0);
	if (pm_device_on_power_domain(dev)) {
		pm_device_init_off(dev);
	} else {
		pm_device_init_suspended(dev);
	}

	return pm_device_runtime_enable(dev);
};


#define DAI_INTEL_DMIC_DEVICE_INIT(n)					\
	static struct dai_properties dai_intel_dmic_properties_##n;	\
									\
	static struct dai_intel_dmic dai_intel_dmic_data_##n =		\
	{	.dai_config_params =					\
		{							\
			.type = DAI_INTEL_DMIC,				\
			.dai_index = n					\
		},							\
		.reg_base = DT_INST_REG_ADDR_BY_IDX(n, 0),		\
		.shim_base = DT_INST_PROP(n, shim),			\
		IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(hdamlddmic)),	\
			(.hdamldmic_base = DT_REG_ADDR(DT_NODELABEL(hdamlddmic)),))	\
		IF_ENABLED(DT_NODE_EXISTS(DT_NODELABEL(dmicvss)),	\
			(.vshim_base = DT_REG_ADDR(DT_NODELABEL(dmicvss)),))	\
		.irq = DT_INST_IRQN(n),					\
		.fifo =							\
		{							\
			.offset = DT_INST_REG_ADDR_BY_IDX(n, 0)		\
				+ DT_INST_PROP(n, fifo),		\
			.handshake = DMA_HANDSHAKE_DMIC_CH##n		\
		},							\
	};								\
									\
	PM_DEVICE_DT_INST_DEFINE(n, dmic_pm_action);			\
									\
	DEVICE_DT_INST_DEFINE(n,					\
		dai_dmic_initialize_device,				\
		PM_DEVICE_DT_INST_GET(n),				\
		&dai_intel_dmic_data_##n,				\
		&dai_intel_dmic_properties_##n,				\
		POST_KERNEL,						\
		CONFIG_DAI_INIT_PRIORITY,				\
		&dai_dmic_ops);

DT_INST_FOREACH_STATUS_OKAY(DAI_INTEL_DMIC_DEVICE_INIT)
