/*
 * 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/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 */

#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;

	/* DMIC Change sync period */
	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPRD(val),
			dmic->shim_base + DMICSYNC_OFFSET);
	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
			dmic->shim_base + DMICSYNC_OFFSET);
}

static inline void dai_dmic_clear_sync_period(const struct dai_intel_dmic *dmic)
{
	/* DMIC Clean sync period */
	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) & ~DMICSYNC_SYNCPRD(0x0000),
			dmic->shim_base + DMICSYNC_OFFSET);
	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) & ~DMICSYNC_CMDSYNC,
			dmic->shim_base + DMICSYNC_OFFSET);

}

/* Preparing for command synchronization on multiple link segments */
static inline void dai_dmic_sync_prepare(const struct dai_intel_dmic *dmic)
{
	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
			dmic->shim_base + DMICSYNC_OFFSET);
}

/* Trigering synchronization of command execution */
static void dmic_sync_trigger(const struct dai_intel_dmic *dmic)
{
	__ASSERT_NO_MSG((sys_read32(dmic->shim_base + DMICSYNC_OFFSET) & DMICSYNC_CMDSYNC) != 0);

	sys_write32(sys_read32(dmic->shim_base + DMICSYNC_OFFSET) |
		    DMICSYNC_SYNCGO, dmic->shim_base + DMICSYNC_OFFSET);
	/* waiting for CMDSYNC bit clearing */
	while (sys_read32(dmic->shim_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)
{
#ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15
	uint32_t shim_reg;

	shim_reg = sys_read32(SHIM_CLKCTL) | SHIM_CLKCTL_DMICFDCGB;

	sys_write32(shim_reg, SHIM_CLKCTL);

	LOG_INF("dis-dmic-clk-gating CLKCTL %08x", shim_reg);
#else
	/* Disable DMIC clock gating */
	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)
{
#ifdef CONFIG_SOC_SERIES_INTEL_CAVS_V15
	uint32_t shim_reg;

	shim_reg = sys_read32(SHIM_CLKCTL) & ~SHIM_CLKCTL_DMICFDCGB;

	sys_write32(shim_reg, SHIM_CLKCTL);

	LOG_INF("en-dmic-clk-gating CLKCTL %08x", shim_reg);
#else
	/* Enable DMIC clock gating */
	sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & ~DMIC_DCGD),
			dmic->shim_base + DMICLCTL_OFFSET);
#endif
}

static inline void dai_dmic_en_power(const struct dai_intel_dmic *dmic)
{
#ifndef CONFIG_SOC_SERIES_INTEL_CAVS_V15
	/* Enable DMIC power */
	sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) | DMICLCTL_SPA),
			dmic->shim_base + DMICLCTL_OFFSET);
#endif
}
static inline void dai_dmic_dis_power(const struct dai_intel_dmic *dmic)
{
#ifndef CONFIG_SOC_SERIES_INTEL_CAVS_V15
	/* Disable DMIC power */
	sys_write32((sys_read32(dmic->shim_base + DMICLCTL_OFFSET) & (~DMICLCTL_SPA)),
			dmic->shim_base + DMICLCTL_OFFSET);
#endif
}

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_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++) {
		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;
		}
	}

	/* 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 const struct dai_config *dai_dmic_get_config(const struct device *dev, enum dai_dir dir)
{
	struct dai_intel_dmic *dmic = (struct dai_intel_dmic *)dev->data;

	__ASSERT_NO_MSG(dir == DAI_DIR_RX);
	return &dmic->dai_config_params;
}

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

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

const struct dai_driver_api dai_dmic_ops = {
	.probe			= dai_dmic_probe_wrapper,
	.remove			= dai_dmic_remove_wrapper,
	.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);
	return 0;
};


#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),			\
		.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		\
		},							\
	};								\
									\
	DEVICE_DT_INST_DEFINE(n,					\
		dai_dmic_initialize_device,				\
		NULL,							\
		&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)
