// 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

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;
};

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 (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 (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;

	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 int mchp_pdmc_close(struct snd_soc_component *component,
			   struct snd_pcm_substream *substream)
{
	return snd_soc_add_component_controls(component, mchp_pdmc_snd_controls,
					      ARRAY_SIZE(mchp_pdmc_snd_controls));
}

static int mchp_pdmc_open(struct snd_soc_component *component,
			  struct snd_pcm_substream *substream)
{
	int i;

	/* remove controls that can't be changed at runtime */
	for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
		const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
		struct snd_ctl_elem_id id;
		struct snd_kcontrol *kctl;
		int err;

		if (component->name_prefix)
			snprintf(id.name, sizeof(id.name), "%s %s", component->name_prefix,
				 control->name);
		else
			strscpy(id.name, control->name, sizeof(id.name));

		id.numid = 0;
		id.iface = control->iface;
		id.device = control->device;
		id.subdevice = control->subdevice;
		id.index = control->index;
		kctl = snd_ctl_find_id(component->card->snd_card, &id);
		if (!kctl) {
			dev_err(component->dev, "Failed to find %s\n", control->name);
			continue;
		}
		err = snd_ctl_remove(component->card->snd_card, kctl);
		if (err < 0) {
			dev_err(component->dev, "%d: Failed to remove %s\n", err,
				control->name);
			continue;
		}
	}

	return 0;
}

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),
	.open = &mchp_pdmc_open,
	.close = &mchp_pdmc_close,
	.legacy_dai_naming = 1,
	.start_dma_last = 1,
};

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)
{
	if (!(period_size % 8))
		return 8;
	if (!(period_size % 4))
		return 4;
	if (!(period_size % 2))
		return 2;
	return 1;
}

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);
	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\n",
		__func__, params_rate(params), params_format(params),
		params_width(params), params_channels(params));

	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);
	}

	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);

	dd->addr.maxburst = mchp_pdmc_period_to_maxburst(snd_pcm_lib_period_bytes(substream));
	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 const struct snd_soc_dai_ops mchp_pdmc_dai_ops = {
	.set_fmt	= mchp_pdmc_set_fmt,
	.startup	= mchp_pdmc_startup,
	.hw_params	= mchp_pdmc_hw_params,
	.trigger	= mchp_pdmc_trigger,
};

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 struct snd_soc_dai_driver mchp_pdmc_dai = {
	.probe	= mchp_pdmc_dai_probe,
	.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,
	.pcm_new = &mchp_pdmc_pcm_new,
};

/* 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,
			     void *buf, 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);

	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_new = 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");
