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

#define DT_DRV_COMPAT st_mpxxdtyy

#include <zephyr/devicetree.h>

#include "mpxxdtyy.h"

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

#define CHANNEL_MASK	0x55

static uint8_t ch_demux[128] = {
  0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
  0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
  0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
  0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
  0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
  0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03,
  0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
  0x04, 0x05, 0x04, 0x05, 0x06, 0x07, 0x06, 0x07,
  0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
  0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
  0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
  0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
  0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
  0x08, 0x09, 0x08, 0x09, 0x0a, 0x0b, 0x0a, 0x0b,
  0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f,
  0x0c, 0x0d, 0x0c, 0x0d, 0x0e, 0x0f, 0x0e, 0x0f
};

static uint8_t left_channel(uint8_t a, uint8_t b)
{
	return ch_demux[a & CHANNEL_MASK] | (ch_demux[b & CHANNEL_MASK] << 4);
}

static uint8_t right_channel(uint8_t a, uint8_t b)
{
	a >>= 1;
	b >>= 1;
	return ch_demux[a & CHANNEL_MASK] | (ch_demux[b & CHANNEL_MASK] << 4);
}

uint16_t sw_filter_lib_init(const struct device *dev, struct dmic_cfg *cfg)
{
	struct mpxxdtyy_data *const data = dev->data;
	TPDMFilter_InitStruct *pdm_filter = &data->pdm_filter[0];
	uint16_t factor;
	uint32_t audio_freq = cfg->streams->pcm_rate;
	int i;

	/* calculate oversampling factor based on pdm clock */
	for (factor = 64U; factor <= 128U; factor += 64U) {
		uint32_t pdm_bit_clk = (audio_freq * factor *
				     cfg->channel.req_num_chan);

		if (pdm_bit_clk >= cfg->io.min_pdm_clk_freq &&
		    pdm_bit_clk <= cfg->io.max_pdm_clk_freq) {
			break;
		}
	}

	if (factor != 64U && factor != 128U) {
		return 0;
	}

	for (i = 0; i < cfg->channel.req_num_chan; i++) {
		/* init the filter lib */
		pdm_filter[i].LP_HZ = audio_freq / 2U;
		pdm_filter[i].HP_HZ = 10;
		pdm_filter[i].Fs = audio_freq;
		pdm_filter[i].Out_MicChannels = cfg->channel.req_num_chan;
		pdm_filter[i].In_MicChannels = cfg->channel.req_num_chan;
		pdm_filter[i].Decimation = factor;
		pdm_filter[i].MaxVolume = 64;

		Open_PDM_Filter_Init(&data->pdm_filter[i]);
	}

	return factor;
}

int sw_filter_lib_run(TPDMFilter_InitStruct *pdm_filter,
		      void *pdm_block, void *pcm_block,
		      size_t pdm_size, size_t pcm_size)
{
	int i, j;
	int pdm_offset;
	uint8_t a, b;

	if (pdm_block == NULL || pcm_block == NULL || pdm_filter == NULL) {
		return -EINVAL;
	}

	for (i = 0; i < pdm_size/2; i++) {
		switch (pdm_filter[0].In_MicChannels) {
		case 1: /* MONO */
			((uint16_t *)pdm_block)[i] = HTONS(((uint16_t *)pdm_block)[i]);
			break;

		case 2: /* STEREO */
			if (pdm_filter[0].In_MicChannels > 1) {
				a = ((uint8_t *)pdm_block)[2*i];
				b = ((uint8_t *)pdm_block)[2*i + 1];

				((uint8_t *)pdm_block)[2*i] = left_channel(a, b);
				((uint8_t *)pdm_block)[2*i + 1] = right_channel(a, b);
			}
			break;

		default:
			return -EINVAL;
		}
	}

	for (j = 0; j < pcm_size / 2; j += pdm_filter[0].Fs / 1000) {
		/*
		 * The number of PDM bytes per PCM sample is the decimation factor
		 * divided by the number of bits per byte (8). We need to skip a number of
		 * PDM bytes equivalent to the number of PCM samples, times the number of
		 * channels.
		 */
		pdm_offset = j * (pdm_filter[0].Decimation / 8) * pdm_filter[0].In_MicChannels;

		for (i = 0; i < pdm_filter[0].In_MicChannels; i++) {
			switch (pdm_filter[0].Decimation) {
			case 64:
				Open_PDM_Filter_64(&((uint8_t *) pdm_block)[pdm_offset + i],
						&((uint16_t *) pcm_block)[j + i],
						pdm_filter->MaxVolume,
						&pdm_filter[i]);
				break;

			case 128:
				Open_PDM_Filter_128(&((uint8_t *) pdm_block)[pdm_offset + i],
						&((uint16_t *) pcm_block)[j + i],
						pdm_filter->MaxVolume,
						&pdm_filter[i]);
				break;

			default:
				return -EINVAL;
			}
		}
	}

	return 0;
}

static const struct _dmic_ops mpxxdtyy_driver_api = {
#if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2s)
	.configure		= mpxxdtyy_i2s_configure,
	.trigger		= mpxxdtyy_i2s_trigger,
	.read			= mpxxdtyy_i2s_read,
#endif /* DT_ANY_INST_ON_BUS_STATUS_OKAY(i2s) */
};

static int mpxxdtyy_initialize(const struct device *dev)
{
	const struct mpxxdtyy_config *config = dev->config;
	struct mpxxdtyy_data *const data = dev->data;

	if (!device_is_ready(config->comm_master)) {
		return -ENODEV;
	}

	data->state = DMIC_STATE_INITIALIZED;
	return 0;
}

static const struct mpxxdtyy_config mpxxdtyy_config = {
	.comm_master = DEVICE_DT_GET(DT_INST_BUS(0)),
};

static struct mpxxdtyy_data mpxxdtyy_data;

DEVICE_DT_INST_DEFINE(0, mpxxdtyy_initialize, NULL, &mpxxdtyy_data,
		      &mpxxdtyy_config, POST_KERNEL,
		      CONFIG_AUDIO_DMIC_INIT_PRIORITY, &mpxxdtyy_driver_api);
