// SPDX-License-Identifier: GPL-2.0
//
// Driver for Microchip Pulse Density Microphone Controller (PDMC) interfaces
//
// Copyright (C) 2019-2022 Microchip Technology Inc. and its subsidiaries
//
// Author: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>

#include <dt-bindings/sound/microchip,pdmc.h>

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>

#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>

/*
 * ---- PDMC Register map ----
 */
#define MCHP_PDMC_CR			0x00	/* Control Register */
#define MCHP_PDMC_MR			0x04	/* Mode Register */
#define MCHP_PDMC_CFGR			0x08	/* Configuration Register */
#define MCHP_PDMC_RHR			0x0C	/* Receive Holding Register */
#define MCHP_PDMC_IER			0x14	/* Interrupt Enable Register */
#define MCHP_PDMC_IDR			0x18	/* Interrupt Disable Register */
#define MCHP_PDMC_IMR			0x1C	/* Interrupt Mask Register */
#define MCHP_PDMC_ISR			0x20	/* Interrupt Status Register */
#define MCHP_PDMC_VER			0x50	/* Version Register */

/*
 * ---- Control Register (Write-only) ----
 */
#define MCHP_PDMC_CR_SWRST		BIT(0)	/* Software Reset */

/*
 * ---- Mode Register (Read/Write) ----
 */
#define MCHP_PDMC_MR_PDMCEN_MASK	GENMASK(3, 0)
#define MCHP_PDMC_MR_PDMCEN(ch)		(BIT(ch) & MCHP_PDMC_MR_PDMCEN_MASK)

#define MCHP_PDMC_MR_OSR_MASK		GENMASK(17, 16)
#define MCHP_PDMC_MR_OSR64		(1 << 16)
#define MCHP_PDMC_MR_OSR128		(2 << 16)
#define MCHP_PDMC_MR_OSR256		(3 << 16)

#define MCHP_PDMC_MR_SINCORDER_MASK	GENMASK(23, 20)

#define MCHP_PDMC_MR_SINC_OSR_MASK	GENMASK(27, 24)
#define MCHP_PDMC_MR_SINC_OSR_DIS	(0 << 24)
#define MCHP_PDMC_MR_SINC_OSR_8		(1 << 24)
#define MCHP_PDMC_MR_SINC_OSR_16	(2 << 24)
#define MCHP_PDMC_MR_SINC_OSR_32	(3 << 24)
#define MCHP_PDMC_MR_SINC_OSR_64	(4 << 24)
#define MCHP_PDMC_MR_SINC_OSR_128	(5 << 24)
#define MCHP_PDMC_MR_SINC_OSR_256	(6 << 24)

#define MCHP_PDMC_MR_CHUNK_MASK		GENMASK(31, 28)

/*
 * ---- Configuration Register (Read/Write) ----
 */
#define MCHP_PDMC_CFGR_BSSEL_MASK	(BIT(0) | BIT(2) | BIT(4) | BIT(6))
#define MCHP_PDMC_CFGR_BSSEL(ch)	BIT((ch) * 2)

#define MCHP_PDMC_CFGR_PDMSEL_MASK	(BIT(16) | BIT(18) | BIT(20) | BIT(22))
#define MCHP_PDMC_CFGR_PDMSEL(ch)	BIT((ch) * 2 + 16)

/*
 * ---- Interrupt Enable/Disable/Mask/Status Registers ----
 */
#define MCHP_PDMC_IR_RXRDY		BIT(0)
#define MCHP_PDMC_IR_RXEMPTY		BIT(1)
#define MCHP_PDMC_IR_RXFULL		BIT(2)
#define MCHP_PDMC_IR_RXCHUNK		BIT(3)
#define MCHP_PDMC_IR_RXUDR		BIT(4)
#define MCHP_PDMC_IR_RXOVR		BIT(5)

/*
 * ---- Version Register (Read-only) ----
 */
#define MCHP_PDMC_VER_VERSION		GENMASK(11, 0)

#define MCHP_PDMC_MAX_CHANNELS		4
#define MCHP_PDMC_DS_NO			2
#define MCHP_PDMC_EDGE_NO		2

/*
 * ---- DMA chunk size allowed ----
 */
#define MCHP_PDMC_DMA_8_WORD_CHUNK			8
#define MCHP_PDMC_DMA_4_WORD_CHUNK			4
#define MCHP_PDMC_DMA_2_WORD_CHUNK			2
#define MCHP_PDMC_DMA_1_WORD_CHUNK			1
#define DMA_BURST_ALIGNED(_p, _s, _w)		!(_p % (_s * _w))

struct mic_map {
	int ds_pos;
	int clk_edge;
};

struct mchp_pdmc_chmap {
	struct snd_pcm_chmap_elem *chmap;
	struct mchp_pdmc *dd;
	struct snd_pcm *pcm;
	struct snd_kcontrol *kctl;
};

struct mchp_pdmc {
	struct mic_map channel_mic_map[MCHP_PDMC_MAX_CHANNELS];
	struct device *dev;
	struct snd_dmaengine_dai_dma_data addr;
	struct regmap *regmap;
	struct clk *pclk;
	struct clk *gclk;
	u32 pdmcen;
	u32 suspend_irq;
	u32 startup_delay_us;
	int mic_no;
	int sinc_order;
	bool audio_filter_en;
	atomic_t busy_stream;
};

static const char *const mchp_pdmc_sinc_filter_order_text[] = {
	"1", "2", "3", "4", "5"
};

static const unsigned int mchp_pdmc_sinc_filter_order_values[] = {
	1, 2, 3, 4, 5,
};

static const struct soc_enum mchp_pdmc_sinc_filter_order_enum = {
	.items = ARRAY_SIZE(mchp_pdmc_sinc_filter_order_text),
	.texts = mchp_pdmc_sinc_filter_order_text,
	.values = mchp_pdmc_sinc_filter_order_values,
};

static int mchp_pdmc_sinc_order_get(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int item;

	item = snd_soc_enum_val_to_item(e, dd->sinc_order);
	uvalue->value.enumerated.item[0] = item;

	return 0;
}

static int mchp_pdmc_sinc_order_put(struct snd_kcontrol *kcontrol,
				    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int *item = uvalue->value.enumerated.item;
	unsigned int val;

	if (item[0] >= e->items)
		return -EINVAL;

	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;

	if (atomic_read(&dd->busy_stream))
		return -EBUSY;

	if (val == dd->sinc_order)
		return 0;

	dd->sinc_order = val;

	return 1;
}

static int mchp_pdmc_af_get(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);

	uvalue->value.integer.value[0] = !!dd->audio_filter_en;

	return 0;
}

static int mchp_pdmc_af_put(struct snd_kcontrol *kcontrol,
			    struct snd_ctl_elem_value *uvalue)
{
	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
	bool af = uvalue->value.integer.value[0] ? true : false;

	if (atomic_read(&dd->busy_stream))
		return -EBUSY;

	if (dd->audio_filter_en == af)
		return 0;

	dd->audio_filter_en = af;

	return 1;
}

static int mchp_pdmc_chmap_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
	struct mchp_pdmc_chmap *info = snd_kcontrol_chip(kcontrol);

	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = info->dd->mic_no;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = SNDRV_CHMAP_RR; /* maxmimum 4 channels */
	return 0;
}

static inline struct snd_pcm_substream *
mchp_pdmc_chmap_substream(struct mchp_pdmc_chmap *info, unsigned int idx)
{
	struct snd_pcm_substream *s;

	for (s = info->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; s; s = s->next)
		if (s->number == idx)
			return s;
	return NULL;
}

static struct snd_pcm_chmap_elem *mchp_pdmc_chmap_get(struct snd_pcm_substream *substream,
						      struct mchp_pdmc_chmap *ch_info)
{
	struct snd_pcm_chmap_elem *map;

	for (map = ch_info->chmap; map->channels; map++) {
		if (map->channels == substream->runtime->channels)
			return map;
	}
	return NULL;
}

static int mchp_pdmc_chmap_ctl_get(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	struct mchp_pdmc_chmap *info = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = info->dd;
	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
	struct snd_pcm_substream *substream;
	const struct snd_pcm_chmap_elem *map;
	int i;
	u32 cfgr_val = 0;

	if (!info->chmap)
		return -EINVAL;
	substream = mchp_pdmc_chmap_substream(info, idx);
	if (!substream)
		return -ENODEV;
	memset(ucontrol->value.integer.value, 0, sizeof(long) * info->dd->mic_no);
	if (!substream->runtime)
		return 0; /* no channels set */

	map = mchp_pdmc_chmap_get(substream, info);
	if (!map)
		return -EINVAL;

	for (i = 0; i < map->channels; i++) {
		int map_idx = map->channels == 1 ? map->map[i] - SNDRV_CHMAP_MONO :
						   map->map[i] - SNDRV_CHMAP_FL;

		/* make sure the reported channel map is the real one, so write the map */
		if (dd->channel_mic_map[map_idx].ds_pos)
			cfgr_val |= MCHP_PDMC_CFGR_PDMSEL(i);
		if (dd->channel_mic_map[map_idx].clk_edge)
			cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);

		ucontrol->value.integer.value[i] = map->map[i];
	}

	regmap_write(dd->regmap, MCHP_PDMC_CFGR, cfgr_val);

	return 0;
}

static int mchp_pdmc_chmap_ctl_put(struct snd_kcontrol *kcontrol,
				   struct snd_ctl_elem_value *ucontrol)
{
	struct mchp_pdmc_chmap *info = snd_kcontrol_chip(kcontrol);
	struct mchp_pdmc *dd = info->dd;
	unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
	struct snd_pcm_substream *substream;
	struct snd_pcm_chmap_elem *map;
	u32 cfgr_val = 0;
	int i;

	if (!info->chmap)
		return -EINVAL;
	substream = mchp_pdmc_chmap_substream(info, idx);
	if (!substream)
		return -ENODEV;

	if (!substream->runtime)
		return 0; /* just for avoiding error from alsactl restore */

	map = mchp_pdmc_chmap_get(substream, info);
	if (!map)
		return -EINVAL;

	for (i = 0; i < map->channels; i++) {
		int map_idx;

		map->map[i] = ucontrol->value.integer.value[i];
		map_idx = map->channels == 1 ? map->map[i] - SNDRV_CHMAP_MONO :
					       map->map[i] - SNDRV_CHMAP_FL;

		/* configure IP for the desired channel map */
		if (dd->channel_mic_map[map_idx].ds_pos)
			cfgr_val |= MCHP_PDMC_CFGR_PDMSEL(i);
		if (dd->channel_mic_map[map_idx].clk_edge)
			cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
	}

	regmap_write(dd->regmap, MCHP_PDMC_CFGR, cfgr_val);

	return 0;
}

static void mchp_pdmc_chmap_ctl_private_free(struct snd_kcontrol *kcontrol)
{
	struct mchp_pdmc_chmap *info = snd_kcontrol_chip(kcontrol);

	info->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl = NULL;
	kfree(info);
}

static int mchp_pdmc_chmap_ctl_tlv(struct snd_kcontrol *kcontrol, int op_flag,
				   unsigned int size, unsigned int __user *tlv)
{
	struct mchp_pdmc_chmap *info = snd_kcontrol_chip(kcontrol);
	const struct snd_pcm_chmap_elem *map;
	unsigned int __user *dst;
	int c, count = 0;

	if (!info->chmap)
		return -EINVAL;
	if (size < 8)
		return -ENOMEM;
	if (put_user(SNDRV_CTL_TLVT_CONTAINER, tlv))
		return -EFAULT;
	size -= 8;
	dst = tlv + 2;
	for (map = info->chmap; map->channels; map++) {
		int chs_bytes = map->channels * 4;

		if (size < 8)
			return -ENOMEM;
		if (put_user(SNDRV_CTL_TLVT_CHMAP_VAR, dst) ||
		    put_user(chs_bytes, dst + 1))
			return -EFAULT;
		dst += 2;
		size -= 8;
		count += 8;
		if (size < chs_bytes)
			return -ENOMEM;
		size -= chs_bytes;
		count += chs_bytes;
		for (c = 0; c < map->channels; c++) {
			if (put_user(map->map[c], dst))
				return -EFAULT;
			dst++;
		}
	}
	if (put_user(count, tlv + 1))
		return -EFAULT;
	return 0;
}

static const struct snd_kcontrol_new mchp_pdmc_snd_controls[] = {
	SOC_SINGLE_BOOL_EXT("Audio Filter", 0, &mchp_pdmc_af_get, &mchp_pdmc_af_put),
	{
		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
		.name = "SINC Filter Order",
		.info = snd_soc_info_enum_double,
		.get = mchp_pdmc_sinc_order_get,
		.put = mchp_pdmc_sinc_order_put,
		.private_value = (unsigned long)&mchp_pdmc_sinc_filter_order_enum,
	},
};

static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
	.name = "mchp-pdmc",
	.controls = mchp_pdmc_snd_controls,
	.num_controls = ARRAY_SIZE(mchp_pdmc_snd_controls),
};

static const unsigned int mchp_pdmc_1mic[] = {1};
static const unsigned int mchp_pdmc_2mic[] = {1, 2};
static const unsigned int mchp_pdmc_3mic[] = {1, 2, 3};
static const unsigned int mchp_pdmc_4mic[] = {1, 2, 3, 4};

static const struct snd_pcm_hw_constraint_list mchp_pdmc_chan_constr[] = {
	{
		.list = mchp_pdmc_1mic,
		.count = ARRAY_SIZE(mchp_pdmc_1mic),
	},
	{
		.list = mchp_pdmc_2mic,
		.count = ARRAY_SIZE(mchp_pdmc_2mic),
	},
	{
		.list = mchp_pdmc_3mic,
		.count = ARRAY_SIZE(mchp_pdmc_3mic),
	},
	{
		.list = mchp_pdmc_4mic,
		.count = ARRAY_SIZE(mchp_pdmc_4mic),
	},
};

static int mchp_pdmc_startup(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);

	regmap_write(dd->regmap, MCHP_PDMC_CR, MCHP_PDMC_CR_SWRST);

	snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
				   &mchp_pdmc_chan_constr[dd->mic_no - 1]);

	return 0;
}

static int mchp_pdmc_dai_probe(struct snd_soc_dai *dai)
{
	struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);

	snd_soc_dai_init_dma_data(dai, NULL, &dd->addr);

	return 0;
}

static int mchp_pdmc_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
	unsigned int fmt_master = fmt & SND_SOC_DAIFMT_MASTER_MASK;
	unsigned int fmt_format = fmt & SND_SOC_DAIFMT_FORMAT_MASK;

	/* IP needs to be bitclock master */
	if (fmt_master != SND_SOC_DAIFMT_BP_FP &&
	    fmt_master != SND_SOC_DAIFMT_BP_FC)
		return -EINVAL;

	/* IP supports only PDM interface */
	if (fmt_format != SND_SOC_DAIFMT_PDM)
		return -EINVAL;

	return 0;
}

static u32 mchp_pdmc_mr_set_osr(int audio_filter_en, unsigned int osr)
{
	if (audio_filter_en) {
		switch (osr) {
		case 64:
			return MCHP_PDMC_MR_OSR64;
		case 128:
			return MCHP_PDMC_MR_OSR128;
		case 256:
			return MCHP_PDMC_MR_OSR256;
		}
	} else {
		switch (osr) {
		case 8:
			return MCHP_PDMC_MR_SINC_OSR_8;
		case 16:
			return MCHP_PDMC_MR_SINC_OSR_16;
		case 32:
			return MCHP_PDMC_MR_SINC_OSR_32;
		case 64:
			return MCHP_PDMC_MR_SINC_OSR_64;
		case 128:
			return MCHP_PDMC_MR_SINC_OSR_128;
		case 256:
			return MCHP_PDMC_MR_SINC_OSR_256;
		}
	}
	return 0;
}

static inline int mchp_pdmc_period_to_maxburst(int period_size, int sample_size)
{
	int p_size = period_size;
	int s_size = sample_size;

	if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_8_WORD_CHUNK))
		return MCHP_PDMC_DMA_8_WORD_CHUNK;
	if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_4_WORD_CHUNK))
		return MCHP_PDMC_DMA_4_WORD_CHUNK;
	if (DMA_BURST_ALIGNED(p_size, s_size, MCHP_PDMC_DMA_2_WORD_CHUNK))
		return MCHP_PDMC_DMA_2_WORD_CHUNK;
	return MCHP_PDMC_DMA_1_WORD_CHUNK;
}

static struct snd_pcm_chmap_elem mchp_pdmc_std_chmaps[] = {
	{ .channels = 1,
	  .map = { SNDRV_CHMAP_MONO } },
	{ .channels = 2,
	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
	{ .channels = 3,
	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
		   SNDRV_CHMAP_RL } },
	{ .channels = 4,
	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
		   SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
	{ }
};

static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *params,
			       struct snd_soc_dai *dai)
{
	struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
	struct snd_soc_component *comp = dai->component;
	unsigned long gclk_rate = 0;
	unsigned long best_diff_rate = ~0UL;
	unsigned int channels = params_channels(params);
	unsigned int osr = 0, osr_start;
	unsigned int fs = params_rate(params);
	int sample_bytes = params_physical_width(params) / 8;
	int period_bytes = params_period_size(params) *
		params_channels(params) * sample_bytes;
	int maxburst;
	u32 mr_val = 0;
	u32 cfgr_val = 0;
	int i;
	int ret;

	dev_dbg(comp->dev, "%s() rate=%u format=%#x width=%u channels=%u period_bytes=%d\n",
		__func__, params_rate(params), params_format(params),
		params_width(params), params_channels(params), period_bytes);

	if (channels > dd->mic_no) {
		dev_err(comp->dev, "more channels %u than microphones %d\n",
			channels, dd->mic_no);
		return -EINVAL;
	}

	dd->pdmcen = 0;
	for (i = 0; i < channels; i++) {
		dd->pdmcen |= MCHP_PDMC_MR_PDMCEN(i);
		if (dd->channel_mic_map[i].ds_pos)
			cfgr_val |= MCHP_PDMC_CFGR_PDMSEL(i);
		if (dd->channel_mic_map[i].clk_edge)
			cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
	}

	/*
	 * from these point forward, we consider the controller busy, so the
	 * audio filter and SINC order can't be changed
	 */
	atomic_set(&dd->busy_stream, 1);
	for (osr_start = dd->audio_filter_en ? 64 : 8;
	     osr_start <= 256 && best_diff_rate; osr_start *= 2) {
		long round_rate;
		unsigned long diff_rate;

		round_rate = clk_round_rate(dd->gclk,
					    (unsigned long)fs * 16 * osr_start);
		if (round_rate < 0)
			continue;
		diff_rate = abs((fs * 16 * osr_start) - round_rate);
		if (diff_rate < best_diff_rate) {
			best_diff_rate = diff_rate;
			osr = osr_start;
			gclk_rate = fs * 16 * osr;
		}
	}
	if (!gclk_rate) {
		dev_err(comp->dev, "invalid sampling rate: %u\n", fs);
		return -EINVAL;
	}

	/* CLK is enabled by runtime PM. */
	clk_disable_unprepare(dd->gclk);

	/* set the rate */
	ret = clk_set_rate(dd->gclk, gclk_rate);
	clk_prepare_enable(dd->gclk);
	if (ret) {
		dev_err(comp->dev, "unable to set rate %lu to GCLK: %d\n",
			gclk_rate, ret);
		return ret;
	}

	mr_val |= mchp_pdmc_mr_set_osr(dd->audio_filter_en, osr);

	mr_val |= FIELD_PREP(MCHP_PDMC_MR_SINCORDER_MASK, dd->sinc_order);

	maxburst = mchp_pdmc_period_to_maxburst(period_bytes, sample_bytes);
	dd->addr.maxburst = maxburst;
	mr_val |= FIELD_PREP(MCHP_PDMC_MR_CHUNK_MASK, dd->addr.maxburst);
	dev_dbg(comp->dev, "maxburst set to %d\n", dd->addr.maxburst);

	snd_soc_component_update_bits(comp, MCHP_PDMC_MR,
				      MCHP_PDMC_MR_OSR_MASK |
				      MCHP_PDMC_MR_SINCORDER_MASK |
				      MCHP_PDMC_MR_SINC_OSR_MASK |
				      MCHP_PDMC_MR_CHUNK_MASK, mr_val);

	snd_soc_component_write(comp, MCHP_PDMC_CFGR, cfgr_val);

	return 0;
}

static void mchp_pdmc_noise_filter_workaround(struct mchp_pdmc *dd)
{
	u32 tmp, steps = 16;

	/*
	 * PDMC doesn't wait for microphones' startup time thus the acquisition
	 * may start before the microphones are ready leading to poc noises at
	 * the beginning of capture. To avoid this, we need to wait 50ms (in
	 * normal startup procedure) or 150 ms (worst case after resume from sleep
	 * states) after microphones are enabled and then clear the FIFOs (by
	 * reading the RHR 16 times) and possible interrupts before continuing.
	 * Also, for this to work the DMA needs to be started after interrupts
	 * are enabled.
	 */
	usleep_range(dd->startup_delay_us, dd->startup_delay_us + 5);

	while (steps--)
		regmap_read(dd->regmap, MCHP_PDMC_RHR, &tmp);

	/* Clear interrupts. */
	regmap_read(dd->regmap, MCHP_PDMC_ISR, &tmp);
}

static int mchp_pdmc_trigger(struct snd_pcm_substream *substream,
			     int cmd, struct snd_soc_dai *dai)
{
	struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
	struct snd_soc_component *cpu = dai->component;
#ifdef DEBUG
	u32 val;
#endif

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
					      MCHP_PDMC_MR_PDMCEN_MASK,
					      dd->pdmcen);

		mchp_pdmc_noise_filter_workaround(dd);

		/* Enable interrupts. */
		regmap_write(dd->regmap, MCHP_PDMC_IER, dd->suspend_irq |
			     MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
		dd->suspend_irq = 0;
		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
		regmap_read(dd->regmap, MCHP_PDMC_IMR, &dd->suspend_irq);
		fallthrough;
	case SNDRV_PCM_TRIGGER_STOP:
		/* Disable overrun and underrun error interrupts */
		regmap_write(dd->regmap, MCHP_PDMC_IDR, dd->suspend_irq |
			     MCHP_PDMC_IR_RXOVR | MCHP_PDMC_IR_RXUDR);
		fallthrough;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		snd_soc_component_update_bits(cpu, MCHP_PDMC_MR,
					      MCHP_PDMC_MR_PDMCEN_MASK, 0);
		break;
	default:
		return -EINVAL;
	}

#ifdef DEBUG
	regmap_read(dd->regmap, MCHP_PDMC_MR, &val);
	dev_dbg(dd->dev, "MR (0x%02x): 0x%08x\n", MCHP_PDMC_MR, val);
	regmap_read(dd->regmap, MCHP_PDMC_CFGR, &val);
	dev_dbg(dd->dev, "CFGR (0x%02x): 0x%08x\n", MCHP_PDMC_CFGR, val);
	regmap_read(dd->regmap, MCHP_PDMC_IMR, &val);
	dev_dbg(dd->dev, "IMR (0x%02x): 0x%08x\n", MCHP_PDMC_IMR, val);
#endif

	return 0;
}

static int mchp_pdmc_add_chmap_ctls(struct snd_pcm *pcm, struct mchp_pdmc *dd)
{
	struct mchp_pdmc_chmap *info;
	struct snd_kcontrol_new knew = {
		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
			SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
		.info = mchp_pdmc_chmap_ctl_info,
		.get = mchp_pdmc_chmap_ctl_get,
		.put = mchp_pdmc_chmap_ctl_put,
		.tlv.c = mchp_pdmc_chmap_ctl_tlv,
	};
	int err;

	if (WARN_ON(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl))
		return -EBUSY;
	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;
	info->pcm = pcm;
	info->dd = dd;
	info->chmap = mchp_pdmc_std_chmaps;
	knew.name = "Capture Channel Map";
	knew.device = pcm->device;
	knew.count = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count;
	info->kctl = snd_ctl_new1(&knew, info);
	if (!info->kctl) {
		kfree(info);
		return -ENOMEM;
	}
	info->kctl->private_free = mchp_pdmc_chmap_ctl_private_free;
	err = snd_ctl_add(pcm->card, info->kctl);
	if (err < 0)
		return err;
	pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl = info->kctl;
	return 0;
}

static int mchp_pdmc_pcm_new(struct snd_soc_pcm_runtime *rtd,
			     struct snd_soc_dai *dai)
{
	struct mchp_pdmc *dd = snd_soc_dai_get_drvdata(dai);
	int ret;

	ret = mchp_pdmc_add_chmap_ctls(rtd->pcm, dd);
	if (ret < 0)
		dev_err(dd->dev, "failed to add channel map controls: %d\n", ret);

	return ret;
}

static const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
	.probe		= mchp_pdmc_dai_probe,
	.set_fmt	= mchp_pdmc_set_fmt,
	.startup	= mchp_pdmc_startup,
	.hw_params	= mchp_pdmc_hw_params,
	.trigger	= mchp_pdmc_trigger,
	.pcm_new	= &mchp_pdmc_pcm_new,
};

static struct snd_soc_dai_driver mchp_pdmc_dai = {
	.name	= "mchp-pdmc",
	.capture = {
		.stream_name	= "Capture",
		.channels_min	= 1,
		.channels_max	= 4,
		.rate_min	= 8000,
		.rate_max	= 192000,
		.rates		= SNDRV_PCM_RATE_KNOT,
		.formats	= SNDRV_PCM_FMTBIT_S24_LE,
	},
	.ops = &mchp_pdmc_dai_ops,
};

/* PDMC interrupt handler */
static irqreturn_t mchp_pdmc_interrupt(int irq, void *dev_id)
{
	struct mchp_pdmc *dd = dev_id;
	u32 isr, msr, pending;
	irqreturn_t ret = IRQ_NONE;

	regmap_read(dd->regmap, MCHP_PDMC_ISR, &isr);
	regmap_read(dd->regmap, MCHP_PDMC_IMR, &msr);

	pending = isr & msr;
	dev_dbg(dd->dev, "ISR (0x%02x): 0x%08x, IMR (0x%02x): 0x%08x, pending: 0x%08x\n",
		MCHP_PDMC_ISR, isr, MCHP_PDMC_IMR, msr, pending);
	if (!pending)
		return IRQ_NONE;

	if (pending & MCHP_PDMC_IR_RXUDR) {
		dev_warn(dd->dev, "underrun detected\n");
		regmap_write(dd->regmap, MCHP_PDMC_IDR, MCHP_PDMC_IR_RXUDR);
		ret = IRQ_HANDLED;
	}
	if (pending & MCHP_PDMC_IR_RXOVR) {
		dev_warn(dd->dev, "overrun detected\n");
		regmap_write(dd->regmap, MCHP_PDMC_IDR, MCHP_PDMC_IR_RXOVR);
		ret = IRQ_HANDLED;
	}

	return ret;
}

/* regmap configuration */
static bool mchp_pdmc_readable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MCHP_PDMC_MR:
	case MCHP_PDMC_CFGR:
	case MCHP_PDMC_IMR:
	case MCHP_PDMC_ISR:
	case MCHP_PDMC_RHR:
	case MCHP_PDMC_VER:
		return true;
	default:
		return false;
	}
}

static bool mchp_pdmc_writeable_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MCHP_PDMC_CR:
	case MCHP_PDMC_MR:
	case MCHP_PDMC_CFGR:
	case MCHP_PDMC_IER:
	case MCHP_PDMC_IDR:
		return true;
	default:
		return false;
	}
}

static bool mchp_pdmc_volatile_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MCHP_PDMC_ISR:
	case MCHP_PDMC_RHR:
		return true;
	default:
		return false;
	}
}

static bool mchp_pdmc_precious_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MCHP_PDMC_RHR:
	case MCHP_PDMC_ISR:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config mchp_pdmc_regmap_config = {
	.reg_bits	= 32,
	.reg_stride	= 4,
	.val_bits	= 32,
	.max_register	= MCHP_PDMC_VER,
	.readable_reg	= mchp_pdmc_readable_reg,
	.writeable_reg	= mchp_pdmc_writeable_reg,
	.precious_reg	= mchp_pdmc_precious_reg,
	.volatile_reg	= mchp_pdmc_volatile_reg,
	.cache_type	= REGCACHE_FLAT,
};

static int mchp_pdmc_dt_init(struct mchp_pdmc *dd)
{
	struct device_node *np = dd->dev->of_node;
	bool mic_ch[MCHP_PDMC_DS_NO][MCHP_PDMC_EDGE_NO] = {0};
	int i;
	int ret;

	if (!np) {
		dev_err(dd->dev, "device node not found\n");
		return -EINVAL;
	}

	dd->mic_no = of_property_count_u32_elems(np, "microchip,mic-pos");
	if (dd->mic_no < 0) {
		dev_err(dd->dev, "failed to get microchip,mic-pos: %d",
			dd->mic_no);
		return dd->mic_no;
	}
	if (!dd->mic_no || dd->mic_no % 2 ||
	    dd->mic_no / 2 > MCHP_PDMC_MAX_CHANNELS) {
		dev_err(dd->dev, "invalid array length for microchip,mic-pos: %d",
			dd->mic_no);
		return -EINVAL;
	}

	dd->mic_no /= 2;

	dev_info(dd->dev, "%d PDM microphones declared\n", dd->mic_no);

	/*
	 * by default, we consider the order of microphones in
	 * microchip,mic-pos to be the same with the channel mapping;
	 * 1st microphone channel 0, 2nd microphone channel 1, etc.
	 */
	for (i = 0; i < dd->mic_no; i++) {
		int ds;
		int edge;

		ret = of_property_read_u32_index(np, "microchip,mic-pos", i * 2,
						 &ds);
		if (ret) {
			dev_err(dd->dev,
				"failed to get value no %d value from microchip,mic-pos: %d",
				i * 2, ret);
			return ret;
		}
		if (ds >= MCHP_PDMC_DS_NO) {
			dev_err(dd->dev,
				"invalid DS index in microchip,mic-pos array: %d",
				ds);
			return -EINVAL;
		}

		ret = of_property_read_u32_index(np, "microchip,mic-pos", i * 2 + 1,
						 &edge);
		if (ret) {
			dev_err(dd->dev,
				"failed to get value no %d value from microchip,mic-pos: %d",
				i * 2 + 1, ret);
			return ret;
		}

		if (edge != MCHP_PDMC_CLK_POSITIVE &&
		    edge != MCHP_PDMC_CLK_NEGATIVE) {
			dev_err(dd->dev,
				"invalid edge in microchip,mic-pos array: %d", edge);
			return -EINVAL;
		}
		if (mic_ch[ds][edge]) {
			dev_err(dd->dev,
				"duplicated mic (DS %d, edge %d) in microchip,mic-pos array",
				ds, edge);
			return -EINVAL;
		}
		mic_ch[ds][edge] = true;
		dd->channel_mic_map[i].ds_pos = ds;
		dd->channel_mic_map[i].clk_edge = edge;
	}

	dd->startup_delay_us = 150000;
	of_property_read_u32(np, "microchip,startup-delay-us", &dd->startup_delay_us);

	return 0;
}

/* used to clean the channel index found on RHR's MSB */
static int mchp_pdmc_process(struct snd_pcm_substream *substream,
			     int channel, unsigned long hwoff,
			     unsigned long bytes)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	u8 *dma_ptr = runtime->dma_area + hwoff +
		      channel * (runtime->dma_bytes / runtime->channels);
	u8 *dma_ptr_end = dma_ptr + bytes;
	unsigned int sample_size = samples_to_bytes(runtime, 1);

	for (; dma_ptr < dma_ptr_end; dma_ptr += sample_size)
		*dma_ptr = 0;

	return 0;
}

static struct snd_dmaengine_pcm_config mchp_pdmc_config = {
	.process = mchp_pdmc_process,
	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
};

static int mchp_pdmc_runtime_suspend(struct device *dev)
{
	struct mchp_pdmc *dd = dev_get_drvdata(dev);

	regcache_cache_only(dd->regmap, true);

	clk_disable_unprepare(dd->gclk);
	clk_disable_unprepare(dd->pclk);

	return 0;
}

static int mchp_pdmc_runtime_resume(struct device *dev)
{
	struct mchp_pdmc *dd = dev_get_drvdata(dev);
	int ret;

	ret = clk_prepare_enable(dd->pclk);
	if (ret) {
		dev_err(dd->dev,
			"failed to enable the peripheral clock: %d\n", ret);
		return ret;
	}
	ret = clk_prepare_enable(dd->gclk);
	if (ret) {
		dev_err(dd->dev,
			"failed to enable generic clock: %d\n", ret);
		goto disable_pclk;
	}

	regcache_cache_only(dd->regmap, false);
	regcache_mark_dirty(dd->regmap);
	ret = regcache_sync(dd->regmap);
	if (ret) {
		regcache_cache_only(dd->regmap, true);
		clk_disable_unprepare(dd->gclk);
disable_pclk:
		clk_disable_unprepare(dd->pclk);
	}

	return ret;
}

static int mchp_pdmc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mchp_pdmc *dd;
	struct resource *res;
	void __iomem *io_base;
	u32 version;
	int irq;
	int ret;

	dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
	if (!dd)
		return -ENOMEM;

	dd->dev = &pdev->dev;
	ret = mchp_pdmc_dt_init(dd);
	if (ret < 0)
		return ret;

	irq = platform_get_irq(pdev, 0);
	if (irq < 0)
		return irq;

	dd->pclk = devm_clk_get(dev, "pclk");
	if (IS_ERR(dd->pclk)) {
		ret = PTR_ERR(dd->pclk);
		dev_err(dev, "failed to get peripheral clock: %d\n", ret);
		return ret;
	}

	dd->gclk = devm_clk_get(dev, "gclk");
	if (IS_ERR(dd->gclk)) {
		ret = PTR_ERR(dd->gclk);
		dev_err(dev, "failed to get GCK: %d\n", ret);
		return ret;
	}

	io_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(io_base)) {
		ret = PTR_ERR(io_base);
		dev_err(dev, "failed to remap register memory: %d\n", ret);
		return ret;
	}

	dd->regmap = devm_regmap_init_mmio(dev, io_base,
					   &mchp_pdmc_regmap_config);
	if (IS_ERR(dd->regmap)) {
		ret = PTR_ERR(dd->regmap);
		dev_err(dev, "failed to init register map: %d\n", ret);
		return ret;
	}

	ret = devm_request_irq(dev, irq, mchp_pdmc_interrupt, 0,
			       dev_name(&pdev->dev), dd);
	if (ret < 0) {
		dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
			irq, ret);
		return ret;
	}

	/* by default audio filter is enabled and the SINC Filter order
	 * will be set to the recommended value, 3
	 */
	dd->audio_filter_en = true;
	dd->sinc_order = 3;

	dd->addr.addr = (dma_addr_t)res->start + MCHP_PDMC_RHR;
	platform_set_drvdata(pdev, dd);

	pm_runtime_enable(dd->dev);
	if (!pm_runtime_enabled(dd->dev)) {
		ret = mchp_pdmc_runtime_resume(dd->dev);
		if (ret)
			return ret;
	}

	/* register platform */
	ret = devm_snd_dmaengine_pcm_register(dev, &mchp_pdmc_config, 0);
	if (ret) {
		dev_err(dev, "could not register platform: %d\n", ret);
		goto pm_runtime_suspend;
	}

	ret = devm_snd_soc_register_component(dev, &mchp_pdmc_dai_component,
					      &mchp_pdmc_dai, 1);
	if (ret) {
		dev_err(dev, "could not register CPU DAI: %d\n", ret);
		goto pm_runtime_suspend;
	}

	/* print IP version */
	regmap_read(dd->regmap, MCHP_PDMC_VER, &version);
	dev_info(dd->dev, "hw version: %#lx\n",
		 version & MCHP_PDMC_VER_VERSION);

	return 0;

pm_runtime_suspend:
	if (!pm_runtime_status_suspended(dd->dev))
		mchp_pdmc_runtime_suspend(dd->dev);
	pm_runtime_disable(dd->dev);

	return ret;
}

static void mchp_pdmc_remove(struct platform_device *pdev)
{
	struct mchp_pdmc *dd = platform_get_drvdata(pdev);

	atomic_set(&dd->busy_stream, 0);

	if (!pm_runtime_status_suspended(dd->dev))
		mchp_pdmc_runtime_suspend(dd->dev);

	pm_runtime_disable(dd->dev);
}

static const struct of_device_id mchp_pdmc_of_match[] = {
	{
		.compatible = "microchip,sama7g5-pdmc",
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, mchp_pdmc_of_match);

static const struct dev_pm_ops mchp_pdmc_pm_ops = {
	SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
	RUNTIME_PM_OPS(mchp_pdmc_runtime_suspend, mchp_pdmc_runtime_resume,
		       NULL)
};

static struct platform_driver mchp_pdmc_driver = {
	.driver	= {
		.name		= "mchp-pdmc",
		.of_match_table	= of_match_ptr(mchp_pdmc_of_match),
		.pm		= pm_ptr(&mchp_pdmc_pm_ops),
	},
	.probe	= mchp_pdmc_probe,
	.remove = mchp_pdmc_remove,
};
module_platform_driver(mchp_pdmc_driver);

MODULE_DESCRIPTION("Microchip PDMC driver under ALSA SoC architecture");
MODULE_AUTHOR("Codrin Ciubotariu <codrin.ciubotariu@microchip.com>");
MODULE_LICENSE("GPL v2");
