/*
 * Copyright (c) 2018 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT st_mpxxdtyy

#include "mpxxdtyy.h"
#include <zephyr/drivers/i2s.h>

#define LOG_LEVEL CONFIG_AUDIO_DMIC_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_DECLARE(mpxxdtyy);

#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2s)

#define NUM_RX_BLOCKS			4
#define PDM_BLOCK_MAX_SIZE_BYTES	512

K_MEM_SLAB_DEFINE(rx_pdm_i2s_mslab, PDM_BLOCK_MAX_SIZE_BYTES, NUM_RX_BLOCKS, 1);

int mpxxdtyy_i2s_read(const struct device *dev, uint8_t stream, void **buffer,
		      size_t *size, int32_t timeout)
{
	int ret;
	const struct mpxxdtyy_config *config = dev->config;
	struct mpxxdtyy_data *const data = dev->data;
	void *pdm_block, *pcm_block;
	size_t pdm_size;
	TPDMFilter_InitStruct *pdm_filter = &data->pdm_filter[0];

	ret = i2s_read(config->comm_master, &pdm_block, &pdm_size);
	if (ret != 0) {
		LOG_ERR("read failed (%d)", ret);
		return ret;
	}

	ret = k_mem_slab_alloc(data->pcm_mem_slab,
			       &pcm_block, K_NO_WAIT);
	if (ret < 0) {
		return ret;
	}

	sw_filter_lib_run(pdm_filter, pdm_block, pcm_block, pdm_size,
			  data->pcm_mem_size);
	k_mem_slab_free(&rx_pdm_i2s_mslab, pdm_block);

	*buffer = pcm_block;
	*size = data->pcm_mem_size;

	return 0;
}

int mpxxdtyy_i2s_trigger(const struct device *dev, enum dmic_trigger cmd)
{
	int ret;
	const struct mpxxdtyy_config *config = dev->config;
	struct mpxxdtyy_data *const data = dev->data;
	enum i2s_trigger_cmd i2s_cmd;
	enum dmic_state tmp_state;

	switch (cmd) {
	case DMIC_TRIGGER_START:
		if (data->state == DMIC_STATE_CONFIGURED) {
			tmp_state = DMIC_STATE_ACTIVE;
			i2s_cmd = I2S_TRIGGER_START;
		} else {
			return 0;
		}
		break;
	case DMIC_TRIGGER_STOP:
		if (data->state == DMIC_STATE_ACTIVE) {
			tmp_state = DMIC_STATE_CONFIGURED;
			i2s_cmd = I2S_TRIGGER_STOP;
		} else {
			return 0;
		}
		break;
	default:
		return -EINVAL;
	}

	ret = i2s_trigger(config->comm_master, I2S_DIR_RX, i2s_cmd);
	if (ret != 0) {
		LOG_ERR("trigger failed with %d error", ret);
		return ret;
	}

	data->state = tmp_state;
	return 0;
}

int mpxxdtyy_i2s_configure(const struct device *dev, struct dmic_cfg *cfg)
{
	int ret;
	const struct mpxxdtyy_config *config = dev->config;
	struct mpxxdtyy_data *const data = dev->data;
	uint8_t chan_size = cfg->streams->pcm_width;
	uint32_t audio_freq = cfg->streams->pcm_rate;
	uint16_t factor;

	/* PCM buffer size */
	data->pcm_mem_slab = cfg->streams->mem_slab;
	data->pcm_mem_size = cfg->streams->block_size;

	/* check requested min pdm frequency */
	if (cfg->io.min_pdm_clk_freq < MPXXDTYY_MIN_PDM_FREQ ||
	    cfg->io.min_pdm_clk_freq > cfg->io.max_pdm_clk_freq) {
		return -EINVAL;
	}

	/* check requested max pdm frequency */
	if (cfg->io.max_pdm_clk_freq > MPXXDTYY_MAX_PDM_FREQ ||
	    cfg->io.max_pdm_clk_freq < cfg->io.min_pdm_clk_freq) {
		return -EINVAL;
	}

	factor = sw_filter_lib_init(dev, cfg);
	if (factor == 0U) {
		return -EINVAL;
	}

	/* configure I2S channels */
	struct i2s_config i2s_cfg;

	i2s_cfg.word_size = chan_size;
	i2s_cfg.channels = cfg->channel.req_num_chan;
	i2s_cfg.format = I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED |
			 I2S_FMT_BIT_CLK_INV;
	i2s_cfg.options = I2S_OPT_FRAME_CLK_MASTER | I2S_OPT_BIT_CLK_MASTER;
	i2s_cfg.frame_clk_freq = audio_freq * factor / chan_size;
	i2s_cfg.block_size = data->pcm_mem_size * (factor / chan_size);
	i2s_cfg.mem_slab = &rx_pdm_i2s_mslab;
	i2s_cfg.timeout = 2000;

	ret = i2s_configure(config->comm_master, I2S_DIR_RX, &i2s_cfg);
	if (ret != 0) {
		LOG_ERR("I2S device configuration error");
		return ret;
	}

	data->state = DMIC_STATE_CONFIGURED;
	return 0;
}
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2s) */
