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

#define DT_DRV_COMPAT st_mpxxdtyy

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

#define LOG_LEVEL CONFIG_AUDIO_DMIC_LOG_LEVEL
#include <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;
	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(data->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;
	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(data->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;
	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(data->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) */
