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

#include <zephyr/ztest.h>
#include <zephyr/kernel.h>

#include <zephyr/toolchain.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#include <zephyr/device.h>
#include <zephyr/drivers/dai.h>
#include <zephyr/drivers/dma.h>
#include <soc.h>

/* sof ssp bespoke data */
struct sof_dai_ssp_params {
	uint32_t reserved0;
	uint16_t reserved1;
	uint16_t mclk_id;

	uint32_t mclk_rate;
	uint32_t fsync_rate;
	uint32_t bclk_rate;

	uint32_t tdm_slots;
	uint32_t rx_slots;
	uint32_t tx_slots;

	uint32_t sample_valid_bits;
	uint16_t tdm_slot_width;
	uint16_t reserved2;

	uint32_t mclk_direction;

	uint16_t frame_pulse_width;
	uint16_t tdm_per_slot_padding_flag;
	uint32_t clks_control;
	uint32_t quirks;
	uint32_t bclk_delay;
} __packed;

static const struct device *const dev_dai_ssp =
	DEVICE_DT_GET(DT_NODELABEL(ssp0));
static const struct device *const dev_dma_dw =
	DEVICE_DT_GET(DT_NODELABEL(lpgpdma0));

static struct dai_config config;
static struct sof_dai_ssp_params ssp_config;

#define BUF_SIZE 48
#define XFER_SIZE BUF_SIZE * 4
#define XFERS 2

K_SEM_DEFINE(xfer_sem, 0, 1);

static struct dma_config dma_cfg = {0};
static struct dma_block_config dma_block_cfgs[XFERS];
static struct dma_config dma_cfg_rx = {0};
static struct dma_block_config dma_block_cfgs_rx[XFERS];

/* 1ms frame of 48Hz sine in 48kHz, thus 48 x 32 bit samples */
static int32_t sine_buf[BUF_SIZE] = {
	0x00000000, 0x10b5150f, 0x2120fb83, 0x30fbc54d,
	0x40000000, 0x4debe4fe, 0x5a82799a, 0x658c9a2d,
	0x6ed9eba1, 0x7641af3d, 0x7ba3751d, 0x7ee7aa4c,
	0x7fffffff, 0x7ee7aa4c, 0x7ba3751d, 0x7641af3d,
	0x6ed9eba1, 0x658c9a2d, 0x5a82799a, 0x4debe4fe,
	0x40000000, 0x30fbc54d, 0x2120fb83, 0x10b5150f,
	0x00000000, 0xef4aeaf1, 0xdedf047d, 0xcf043ab3,
	0xc0000000, 0xb2141b02, 0xa57d8666, 0x9a7365d3,
	0x9126145f, 0x89be50c3, 0x845c8ae3, 0x811855b4,
	0x80000000, 0x811855b4, 0x845c8ae3, 0x89be50c3,
	0x9126145f, 0x9a7365d3, 0xa57d8666, 0xb2141b02,
	0xc0000000, 0xcf043ab3, 0xdedf047d, 0xef4aeaf1,
};

static __aligned(32) int32_t rx_data[XFERS][BUF_SIZE] = { { 0 } };

static void dma_callback(const struct device *dma_dev, void *user_data,
			 uint32_t channel, int status)
{
	if (status < 0) {
		TC_PRINT("tx callback status %d\n", status);
	} else {
		TC_PRINT("tx giving up\n");
	}
}

static void dma_callback_rx(const struct device *dma_dev, void *user_data,
			    uint32_t channel, int status)
{
	if (status < 0) {
		TC_PRINT("rx callback status %d\n", status);
	} else {
		TC_PRINT("rx giving xfer_sem\n");
		k_sem_give(&xfer_sem);
	}
}

static int config_output_dma(const struct dai_properties *props, uint32_t *chan_id)
{
	dma_cfg.dma_slot = props->dma_hs_id;
	dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
	dma_cfg.dest_handshake = 0;
	dma_cfg.source_handshake = 0;
	dma_cfg.cyclic = 1;
	dma_cfg.source_data_size = 1;
	dma_cfg.dest_data_size = 1;
	dma_cfg.source_burst_length = 1;
	dma_cfg.dest_burst_length = 1;
	dma_cfg.user_data = NULL;
	dma_cfg.dma_callback = dma_callback;
	dma_cfg.block_count = XFERS;
	dma_cfg.head_block = dma_block_cfgs;
	dma_cfg.complete_callback_en = false; /* per block completion */

	*chan_id = dma_request_channel(dev_dma_dw, NULL);
	if (*chan_id < 0) {
		TC_PRINT("Platform does not support dma request channel\n");
		return -1;
	}

	memset(dma_block_cfgs, 0, sizeof(dma_block_cfgs));
	for (int i = 0; i < XFERS; i++) {
		dma_block_cfgs[i].block_size = XFER_SIZE;
		dma_block_cfgs[i].source_address = (uint32_t)sine_buf;
		dma_block_cfgs[i].dest_address = props->fifo_address;
		TC_PRINT("dma block %d block_size %d, source addr %x, dest addr %x\n",
			 i, BUF_SIZE, dma_block_cfgs[i].source_address,
			 dma_block_cfgs[i].dest_address);
		if (i < XFERS - 1) {
			dma_block_cfgs[i].next_block = &dma_block_cfgs[i+1];
			TC_PRINT("set next block pointer to %p\n", dma_block_cfgs[i].next_block);
		}
	}

	return 0;
}

static int config_input_dma(const struct dai_properties *props, uint32_t *chan_id_rx)
{
	dma_cfg_rx.dma_slot = props->dma_hs_id;
	dma_cfg_rx.channel_direction = PERIPHERAL_TO_MEMORY;
	dma_cfg_rx.dest_handshake = 0;
	dma_cfg_rx.source_handshake = 0;
	dma_cfg_rx.cyclic = 1;
	dma_cfg_rx.source_data_size = 1;
	dma_cfg_rx.dest_data_size = 1;
	dma_cfg_rx.source_burst_length = 1;
	dma_cfg_rx.dest_burst_length = 1;
	dma_cfg_rx.user_data = NULL;
	dma_cfg_rx.dma_callback = dma_callback_rx;
	dma_cfg_rx.block_count = XFERS;
	dma_cfg_rx.head_block = dma_block_cfgs_rx;
	dma_cfg_rx.complete_callback_en = false; /* per block completion */

	*chan_id_rx = dma_request_channel(dev_dma_dw, NULL);
	if (*chan_id_rx < 0) {
		TC_PRINT("Platform does not support dma request channel\n");
		return -1;
	}

	memset(dma_block_cfgs_rx, 0, sizeof(dma_block_cfgs_rx));
	memset(rx_data, 0, sizeof(rx_data));
	for (int i = 0; i < XFERS; i++) {
		dma_block_cfgs_rx[i].block_size = XFER_SIZE;
		dma_block_cfgs_rx[i].source_address = props->fifo_address;
		dma_block_cfgs_rx[i].dest_address = (uint32_t)rx_data[i];
		TC_PRINT("dma block %d block_size %d, source addr %x, dest addr %x\n",
			 i, BUF_SIZE, dma_block_cfgs_rx[i].source_address,
			 dma_block_cfgs_rx[i].dest_address);
		if (i < XFERS - 1) {
			dma_block_cfgs_rx[i].next_block = &dma_block_cfgs_rx[i+1];
			TC_PRINT("set next block pointer to %p\n", dma_block_cfgs_rx[i].next_block);
		}
	}

	return 0;
}

static int check_transmission(void)
{
	int32_t buffer[2 * BUF_SIZE];
	bool pattern_found = false;
	int32_t pattern[4];
	int start_index;
	int i, j;

	TC_PRINT("Checking transmission:\n");

	/* let's make things easier */
	for (i = 0; i < BUF_SIZE; i++) {
		buffer[i] = rx_data[0][i];
		buffer[BUF_SIZE + i] = rx_data[1][i];
	}

	for (i = 0; i < 4; i++) {
		pattern[i] = sine_buf[i];
	}

	TC_PRINT("tx_data (will be sent 2 times):\n");
	for (i = 0; i < BUF_SIZE; i += 8) {
		for (j = 0; j < 8; j++) {
			TC_PRINT("0x%08x ", sine_buf[i + j]);
		}
		TC_PRINT("\n");
	}
	TC_PRINT("\n");

	TC_PRINT("rx_data:\n");
	for (i = 0; i < BUF_SIZE * 2; i += 8) {
		for (j = 0; j < 8; j++) {
			TC_PRINT("0x%08x ", buffer[i + j]);
		}
		TC_PRINT("\n");
	}
	TC_PRINT("\n");

	/* search for pattern only on first half */
	for (i = 0; i < BUF_SIZE; i++) {
		if (buffer[i] == pattern[0] &&
		    buffer[i + 1] == pattern[1] &&
		    buffer[i + 2] == pattern[2] &&
		    buffer[i + 3] == pattern[3]) {
			pattern_found = true;
			start_index = i;
			break;
		}
	}

	if (!pattern_found) {
		TC_PRINT("pattern not found in rx buffer\n");
		return TC_FAIL;
	}

	TC_PRINT("pattern found in rx buffer an index %d value %x\n", start_index,
		 buffer[start_index]);

	for (i = 0; i < BUF_SIZE; i++) {
		TC_PRINT("tx 0x%08x rx 0x%08x\n", buffer[start_index + i], sine_buf[i]);
		if (buffer[start_index + i] != sine_buf[i]) {
			break;
		}
	}

	if (i < BUF_SIZE - 1) {
		TC_PRINT("transfer differs at index %d\n", i);
		return TC_FAIL;
	}

	return TC_PASS;
}

ZTEST(adsp_ssp, test_adsp_ssp_transfer)
{
	const struct dai_properties *props;
	static int chan_id_rx;
	static int chan_id;

	props = dai_get_properties(dev_dai_ssp, DAI_DIR_TX, 0);
	if (!props) {
		TC_PRINT("Cannot get dai tx properties\n");
		return;
	}

	if (config_output_dma(props, &chan_id)) {
		TC_PRINT("ERROR: config tx dma (%d)\n", chan_id);
		return;
	}

	TC_PRINT("Configuring the dma tx transfer on channel %d\n", chan_id);

	if (dma_config(dev_dma_dw, chan_id, &dma_cfg)) {
		TC_PRINT("ERROR: dma tx config (%d)\n", chan_id);
		return;
	}

	props = dai_get_properties(dev_dai_ssp, DAI_DIR_RX, 0);
	if (!props) {
		TC_PRINT("Cannot get dai rx properties\n");
		return;
	}

	if (config_input_dma(props, &chan_id_rx)) {
		TC_PRINT("ERROR: config rx dma (%d)\n", chan_id);
		return;
	}

	TC_PRINT("Configuring the dma rx transfer on channel %d\n", chan_id_rx);

	if (dma_config(dev_dma_dw, chan_id_rx, &dma_cfg_rx)) {
		TC_PRINT("ERROR: transfer config (%d)\n", chan_id_rx);
		return;
	}

	TC_PRINT("Starting the transfer on channels %d and %d and waiting completion\n", chan_id,
		 chan_id_rx);

	if (dai_trigger(dev_dai_ssp, DAI_DIR_RX, DAI_TRIGGER_PRE_START)) {
		TC_PRINT("ERROR: dai rx pre start\n");
		return;
	}

	if (dai_trigger(dev_dai_ssp, DAI_DIR_TX, DAI_TRIGGER_PRE_START)) {
		TC_PRINT("ERROR: dai tx pre start\n");
		return;
	}

	if (dma_start(dev_dma_dw, chan_id_rx)) {
		TC_PRINT("ERROR: dma rx transfer start (%d)\n", chan_id);
		return;
	}

	if (dma_start(dev_dma_dw, chan_id)) {
		TC_PRINT("ERROR: dma tx transfer start (%d)\n", chan_id);
		return;
	}

	if (dai_trigger(dev_dai_ssp, DAI_DIR_RX, DAI_TRIGGER_START)) {
		TC_PRINT("ERROR: rx dai start\n");
		return;
	}

	if (dai_trigger(dev_dai_ssp, DAI_DIR_TX, DAI_TRIGGER_START)) {
		TC_PRINT("ERROR: tx dai start\n");
		return;
	}


	if (k_sem_take(&xfer_sem, K_MSEC(1000)) != 0) {
		TC_PRINT("timed out waiting for xfers\n");
		return;
	}

	dma_stop(dev_dma_dw, chan_id_rx);
	dma_stop(dev_dma_dw, chan_id);
	dai_trigger(dev_dai_ssp, DAI_DIR_RX, DAI_TRIGGER_STOP);
	dai_trigger(dev_dai_ssp, DAI_DIR_TX, DAI_TRIGGER_STOP);

	check_transmission();
}

ZTEST(adsp_ssp, test_adsp_ssp_config_set)
{
	int ret;

	/* generic config */
	config.type = DAI_INTEL_SSP;
	config.dai_index = 0;
	config.channels = 2;
	config.rate = 48000;
	/*
	 * 1st byte = "ssp mode" = 1 = SOF_DAI_FMT_I2S = I2S mode
	 * 3rd byte = "frame mode" = 0 = SOF_DAI_FMT_NB_NF = normal bit clock + frame
	 * 4th byte = "clocks mode" = 4 = SOF_DAI_FMT_CBC_CFC =
	 * codec bclk consumer & frame consumer
	 */
	config.format = 0x00004001;
	config.options = 0;
	config.word_size = 0;
	config.block_size = 0;

	/* bespoke config */
	ssp_config.mclk_id = 0;
	ssp_config.mclk_rate = 24576000;
	ssp_config.fsync_rate = 48000;
	ssp_config.bclk_rate = 3072000;
	ssp_config.tdm_slots = 2;
	ssp_config.rx_slots = 3;
	ssp_config.tx_slots = 3;
	ssp_config.sample_valid_bits = 32;
	ssp_config.tdm_slot_width = 32;
	ssp_config.mclk_direction = 0;
	ssp_config.frame_pulse_width = 0;
	ssp_config.tdm_per_slot_padding_flag = 0;
	ssp_config.clks_control = 0;
	ssp_config.quirks = 1 << 6; /* loopback bit on */
	ssp_config.bclk_delay = 0;

	ret = dai_config_set(dev_dai_ssp, &config, &ssp_config);

	zassert_equal(ret, TC_PASS);
}

static void test_adsp_ssp_probe(void)
{
	int ret;

	ret = dai_probe(dev_dai_ssp);

	zassert_equal(ret, TC_PASS);
}

static void *adsp_ssp_setup(void)
{
	k_object_access_grant(dev_dai_ssp, k_current_get());

	zassert_true(device_is_ready(dev_dai_ssp), "device SSP_0 is not ready");
	zassert_true(device_is_ready(dev_dma_dw), "device DMA 0 is not ready");

	test_adsp_ssp_probe();

	return NULL;
}

ZTEST_SUITE(adsp_ssp, NULL, adsp_ssp_setup, NULL, NULL, NULL);
