// SPDX-License-Identifier: GPL-2.0-or-later
/* Atmel PDMIC driver
 *
 * Copyright (C) 2015 Atmel
 *
 * Author: Songjun Wu <songjun.wu@atmel.com>
 */

#include <linux/of.h>
#include <linux/clk.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/dmaengine_pcm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include "atmel-pdmic.h"

struct atmel_pdmic_pdata {
	u32 mic_min_freq;
	u32 mic_max_freq;
	s32 mic_offset;
	const char *card_name;
};

struct atmel_pdmic {
	dma_addr_t phy_base;
	struct regmap *regmap;
	struct clk *pclk;
	struct clk *gclk;
	struct device *dev;
	int irq;
	struct snd_pcm_substream *substream;
	const struct atmel_pdmic_pdata *pdata;
};

static const struct of_device_id atmel_pdmic_of_match[] = {
	{
		.compatible = "atmel,sama5d2-pdmic",
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(of, atmel_pdmic_of_match);

#define PDMIC_OFFSET_MAX_VAL	S16_MAX
#define PDMIC_OFFSET_MIN_VAL	S16_MIN

static struct atmel_pdmic_pdata *atmel_pdmic_dt_init(struct device *dev)
{
	struct device_node *np = dev->of_node;
	struct atmel_pdmic_pdata *pdata;

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

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

	if (of_property_read_string(np, "atmel,model", &pdata->card_name))
		pdata->card_name = "PDMIC";

	if (of_property_read_u32(np, "atmel,mic-min-freq",
				 &pdata->mic_min_freq)) {
		dev_err(dev, "failed to get mic-min-freq\n");
		return ERR_PTR(-EINVAL);
	}

	if (of_property_read_u32(np, "atmel,mic-max-freq",
				 &pdata->mic_max_freq)) {
		dev_err(dev, "failed to get mic-max-freq\n");
		return ERR_PTR(-EINVAL);
	}

	if (pdata->mic_max_freq < pdata->mic_min_freq) {
		dev_err(dev,
			"mic-max-freq should not be less than mic-min-freq\n");
		return ERR_PTR(-EINVAL);
	}

	if (of_property_read_s32(np, "atmel,mic-offset", &pdata->mic_offset))
		pdata->mic_offset = 0;

	if (pdata->mic_offset > PDMIC_OFFSET_MAX_VAL) {
		dev_warn(dev,
			 "mic-offset value %d is larger than the max value %d, the max value is specified\n",
			 pdata->mic_offset, PDMIC_OFFSET_MAX_VAL);
		pdata->mic_offset = PDMIC_OFFSET_MAX_VAL;
	} else if (pdata->mic_offset < PDMIC_OFFSET_MIN_VAL) {
		dev_warn(dev,
			 "mic-offset value %d is less than the min value %d, the min value is specified\n",
			 pdata->mic_offset, PDMIC_OFFSET_MIN_VAL);
		pdata->mic_offset = PDMIC_OFFSET_MIN_VAL;
	}

	return pdata;
}

/* cpu dai component */
static int atmel_pdmic_cpu_dai_startup(struct snd_pcm_substream *substream,
					struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
	int ret;

	ret = clk_prepare_enable(dd->gclk);
	if (ret)
		return ret;

	ret =  clk_prepare_enable(dd->pclk);
	if (ret) {
		clk_disable_unprepare(dd->gclk);
		return ret;
	}

	/* Clear all bits in the Control Register(PDMIC_CR) */
	regmap_write(dd->regmap, PDMIC_CR, 0);

	dd->substream = substream;

	/* Enable the overrun error interrupt */
	regmap_write(dd->regmap, PDMIC_IER, PDMIC_IER_OVRE);

	return 0;
}

static void atmel_pdmic_cpu_dai_shutdown(struct snd_pcm_substream *substream,
					struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);

	/* Disable the overrun error interrupt */
	regmap_write(dd->regmap, PDMIC_IDR, PDMIC_IDR_OVRE);

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

static int atmel_pdmic_cpu_dai_prepare(struct snd_pcm_substream *substream,
					struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_component *component = cpu_dai->component;
	u32 val;
	int ret;

	/* Clean the PDMIC Converted Data Register */
	ret = regmap_read(dd->regmap, PDMIC_CDR, &val);
	if (ret < 0)
		return 0;

	ret = snd_soc_component_update_bits(component, PDMIC_CR,
					    PDMIC_CR_ENPDM_MASK,
					    PDMIC_CR_ENPDM_DIS <<
					    PDMIC_CR_ENPDM_SHIFT);
	if (ret < 0)
		return ret;

	return 0;
}

#define ATMEL_PDMIC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)

/* platform */
#define ATMEL_PDMIC_MAX_BUF_SIZE  (64 * 1024)
#define ATMEL_PDMIC_PREALLOC_BUF_SIZE  ATMEL_PDMIC_MAX_BUF_SIZE

static const struct snd_pcm_hardware atmel_pdmic_hw = {
	.info			= SNDRV_PCM_INFO_MMAP
				| SNDRV_PCM_INFO_MMAP_VALID
				| SNDRV_PCM_INFO_INTERLEAVED
				| SNDRV_PCM_INFO_RESUME
				| SNDRV_PCM_INFO_PAUSE,
	.formats		= ATMEL_PDMIC_FORMATS,
	.buffer_bytes_max	= ATMEL_PDMIC_MAX_BUF_SIZE,
	.period_bytes_min	= 256,
	.period_bytes_max	= 32 * 1024,
	.periods_min		= 2,
	.periods_max		= 256,
};

static int
atmel_pdmic_platform_configure_dma(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params,
				struct dma_slave_config *slave_config)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
	int ret;

	ret = snd_hwparams_to_dma_slave_config(substream, params,
					       slave_config);
	if (ret) {
		dev_err(dd->dev,
			"hw params to dma slave configure failed\n");
		return ret;
	}

	slave_config->src_addr		= dd->phy_base + PDMIC_CDR;
	slave_config->src_maxburst	= 1;
	slave_config->dst_maxburst	= 1;

	return 0;
}

static const struct snd_dmaengine_pcm_config
atmel_pdmic_dmaengine_pcm_config = {
	.prepare_slave_config	= atmel_pdmic_platform_configure_dma,
	.pcm_hardware		= &atmel_pdmic_hw,
	.prealloc_buffer_size	= ATMEL_PDMIC_PREALLOC_BUF_SIZE,
};

/* codec */
/* Mic Gain = dgain * 2^(-scale) */
struct mic_gain {
	unsigned int dgain;
	unsigned int scale;
};

/* range from -90 dB to 90 dB */
static const struct mic_gain mic_gain_table[] = {
{    1, 15}, {    1, 14},                           /* -90, -84 dB */
{    3, 15}, {    1, 13}, {    3, 14}, {    1, 12}, /* -81, -78, -75, -72 dB */
{    5, 14}, {   13, 15},                           /* -70, -68 dB */
{    9, 14}, {   21, 15}, {   23, 15}, {   13, 14}, /* -65 ~ -62 dB */
{   29, 15}, {   33, 15}, {   37, 15}, {   41, 15}, /* -61 ~ -58 dB */
{   23, 14}, {   13, 13}, {   58, 15}, {   65, 15}, /* -57 ~ -54 dB */
{   73, 15}, {   41, 14}, {   23, 13}, {   13, 12}, /* -53 ~ -50 dB */
{   29, 13}, {   65, 14}, {   73, 14}, {   41, 13}, /* -49 ~ -46 dB */
{   23, 12}, {  207, 15}, {   29, 12}, {   65, 13}, /* -45 ~ -42 dB */
{   73, 13}, {   41, 12}, {   23, 11}, {  413, 15}, /* -41 ~ -38 dB */
{  463, 15}, {  519, 15}, {  583, 15}, {  327, 14}, /* -37 ~ -34 dB */
{  367, 14}, {  823, 15}, {  231, 13}, { 1036, 15}, /* -33 ~ -30 dB */
{ 1163, 15}, { 1305, 15}, {  183, 12}, { 1642, 15}, /* -29 ~ -26 dB */
{ 1843, 15}, { 2068, 15}, {  145, 11}, { 2603, 15}, /* -25 ~ -22 dB */
{  365, 12}, { 3277, 15}, { 3677, 15}, { 4125, 15}, /* -21 ~ -18 dB */
{ 4629, 15}, { 5193, 15}, { 5827, 15}, { 3269, 14}, /* -17 ~ -14 dB */
{  917, 12}, { 8231, 15}, { 9235, 15}, { 5181, 14}, /* -13 ~ -10 dB */
{11627, 15}, {13045, 15}, {14637, 15}, {16423, 15}, /*  -9 ~ -6 dB */
{18427, 15}, {20675, 15}, { 5799, 13}, {26029, 15}, /*  -5 ~ -2 dB */
{ 7301, 13}, {    1,  0}, {18383, 14}, {10313, 13}, /*  -1 ~ 2 dB */
{23143, 14}, {25967, 14}, {29135, 14}, {16345, 13}, /*   3 ~ 6 dB */
{ 4585, 11}, {20577, 13}, { 1443,  9}, {25905, 13}, /*   7 ~ 10 dB */
{14533, 12}, { 8153, 11}, { 2287,  9}, {20529, 12}, /*  11 ~ 14 dB */
{11517, 11}, { 6461, 10}, {28997, 12}, { 4067,  9}, /*  15 ~ 18 dB */
{18253, 11}, {   10,  0}, {22979, 11}, {25783, 11}, /*  19 ~ 22 dB */
{28929, 11}, {32459, 11}, { 9105,  9}, {20431, 10}, /*  23 ~ 26 dB */
{22925, 10}, {12861,  9}, { 7215,  8}, {16191,  9}, /*  27 ~ 30 dB */
{ 9083,  8}, {20383,  9}, {11435,  8}, { 6145,  7}, /*  31 ~ 34 dB */
{ 3599,  6}, {32305,  9}, {18123,  8}, {20335,  8}, /*  35 ~ 38 dB */
{  713,  3}, {  100,  0}, { 7181,  6}, { 8057,  6}, /*  39 ~ 42 dB */
{  565,  2}, {20287,  7}, {11381,  6}, {25539,  7}, /*  43 ~ 46 dB */
{ 1791,  3}, { 4019,  4}, { 9019,  5}, {20239,  6}, /*  47 ~ 50 dB */
{ 5677,  4}, {25479,  6}, { 7147,  4}, { 8019,  4}, /*  51 ~ 54 dB */
{17995,  5}, {20191,  5}, {11327,  4}, {12709,  4}, /*  55 ~ 58 dB */
{ 3565,  2}, { 1000,  0}, { 1122,  0}, { 1259,  0}, /*  59 ~ 62 dB */
{ 2825,  1}, {12679,  3}, { 7113,  2}, { 7981,  2}, /*  63 ~ 66 dB */
{ 8955,  2}, {20095,  3}, {22547,  3}, {12649,  2}, /*  67 ~ 70 dB */
{28385,  3}, { 3981,  0}, {17867,  2}, {20047,  2}, /*  71 ~ 74 dB */
{11247,  1}, {12619,  1}, {14159,  1}, {31773,  2}, /*  75 ~ 78 dB */
{17825,  1}, {10000,  0}, {11220,  0}, {12589,  0}, /*  79 ~ 82 dB */
{28251,  1}, {15849,  0}, {17783,  0}, {19953,  0}, /*  83 ~ 86 dB */
{22387,  0}, {25119,  0}, {28184,  0}, {31623,  0}, /*  87 ~ 90 dB */
};

static const DECLARE_TLV_DB_RANGE(mic_gain_tlv,
	0, 1, TLV_DB_SCALE_ITEM(-9000, 600, 0),
	2, 5, TLV_DB_SCALE_ITEM(-8100, 300, 0),
	6, 7, TLV_DB_SCALE_ITEM(-7000, 200, 0),
	8, ARRAY_SIZE(mic_gain_table)-1, TLV_DB_SCALE_ITEM(-6500, 100, 0),
);

static int pdmic_get_mic_volsw(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
	unsigned int dgain_val, scale_val;
	int i;

	dgain_val = (snd_soc_component_read(component, PDMIC_DSPR1) & PDMIC_DSPR1_DGAIN_MASK)
		    >> PDMIC_DSPR1_DGAIN_SHIFT;

	scale_val = (snd_soc_component_read(component, PDMIC_DSPR0) & PDMIC_DSPR0_SCALE_MASK)
		    >> PDMIC_DSPR0_SCALE_SHIFT;

	for (i = 0; i < ARRAY_SIZE(mic_gain_table); i++) {
		if ((mic_gain_table[i].dgain == dgain_val) &&
		    (mic_gain_table[i].scale == scale_val))
			ucontrol->value.integer.value[0] = i;
	}

	return 0;
}

static int pdmic_put_mic_volsw(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
	int max = mc->max;
	unsigned int val;
	int ret;

	val = ucontrol->value.integer.value[0];

	if (val > max)
		return -EINVAL;

	ret = snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_MASK,
			 mic_gain_table[val].dgain << PDMIC_DSPR1_DGAIN_SHIFT);
	if (ret < 0)
		return ret;

	ret = snd_soc_component_update_bits(component, PDMIC_DSPR0, PDMIC_DSPR0_SCALE_MASK,
			 mic_gain_table[val].scale << PDMIC_DSPR0_SCALE_SHIFT);
	if (ret < 0)
		return ret;

	return 0;
}

static const struct snd_kcontrol_new atmel_pdmic_snd_controls[] = {
SOC_SINGLE_EXT_TLV("Mic Capture Volume", PDMIC_DSPR1, PDMIC_DSPR1_DGAIN_SHIFT,
		   ARRAY_SIZE(mic_gain_table)-1, 0,
		   pdmic_get_mic_volsw, pdmic_put_mic_volsw, mic_gain_tlv),

SOC_SINGLE("High Pass Filter Switch", PDMIC_DSPR0,
	   PDMIC_DSPR0_HPFBYP_SHIFT, 1, 1),

SOC_SINGLE("SINCC Filter Switch", PDMIC_DSPR0, PDMIC_DSPR0_SINBYP_SHIFT, 1, 1),
};

static int atmel_pdmic_component_probe(struct snd_soc_component *component)
{
	struct snd_soc_card *card = snd_soc_component_get_drvdata(component);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);

	snd_soc_component_update_bits(component, PDMIC_DSPR1, PDMIC_DSPR1_OFFSET_MASK,
		     (u32)(dd->pdata->mic_offset << PDMIC_DSPR1_OFFSET_SHIFT));

	return 0;
}

#define PDMIC_MR_PRESCAL_MAX_VAL 127

static int
atmel_pdmic_cpu_dai_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params,
			      struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_component *component = cpu_dai->component;
	unsigned int rate_min = substream->runtime->hw.rate_min;
	unsigned int rate_max = substream->runtime->hw.rate_max;
	int fs = params_rate(params);
	int bits = params_width(params);
	unsigned long pclk_rate, gclk_rate;
	unsigned int f_pdmic;
	u32 mr_val, dspr0_val, pclk_prescal, gclk_prescal;

	if (params_channels(params) != 1) {
		dev_err(component->dev,
			"only supports one channel\n");
		return -EINVAL;
	}

	if ((fs < rate_min) || (fs > rate_max)) {
		dev_err(component->dev,
			"sample rate is %dHz, min rate is %dHz, max rate is %dHz\n",
			fs, rate_min, rate_max);

		return -EINVAL;
	}

	switch (bits) {
	case 16:
		dspr0_val = (PDMIC_DSPR0_SIZE_16_BITS
			     << PDMIC_DSPR0_SIZE_SHIFT);
		break;
	case 32:
		dspr0_val = (PDMIC_DSPR0_SIZE_32_BITS
			     << PDMIC_DSPR0_SIZE_SHIFT);
		break;
	default:
		return -EINVAL;
	}

	if ((fs << 7) > (rate_max << 6)) {
		f_pdmic = fs << 6;
		dspr0_val |= PDMIC_DSPR0_OSR_64 << PDMIC_DSPR0_OSR_SHIFT;
	} else {
		f_pdmic = fs << 7;
		dspr0_val |= PDMIC_DSPR0_OSR_128 << PDMIC_DSPR0_OSR_SHIFT;
	}

	pclk_rate = clk_get_rate(dd->pclk);
	gclk_rate = clk_get_rate(dd->gclk);

	/* PRESCAL = SELCK/(2*f_pdmic) - 1*/
	pclk_prescal = (u32)(pclk_rate/(f_pdmic << 1)) - 1;
	gclk_prescal = (u32)(gclk_rate/(f_pdmic << 1)) - 1;

	if ((pclk_prescal > PDMIC_MR_PRESCAL_MAX_VAL) ||
	    (gclk_rate/((gclk_prescal + 1) << 1) <
	     pclk_rate/((pclk_prescal + 1) << 1))) {
		mr_val = gclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
		mr_val |= PDMIC_MR_CLKS_GCK << PDMIC_MR_CLKS_SHIFT;
	} else {
		mr_val = pclk_prescal << PDMIC_MR_PRESCAL_SHIFT;
		mr_val |= PDMIC_MR_CLKS_PCK << PDMIC_MR_CLKS_SHIFT;
	}

	snd_soc_component_update_bits(component, PDMIC_MR,
		PDMIC_MR_PRESCAL_MASK | PDMIC_MR_CLKS_MASK, mr_val);

	snd_soc_component_update_bits(component, PDMIC_DSPR0,
		PDMIC_DSPR0_OSR_MASK | PDMIC_DSPR0_SIZE_MASK, dspr0_val);

	return 0;
}

static int atmel_pdmic_cpu_dai_trigger(struct snd_pcm_substream *substream,
				       int cmd, struct snd_soc_dai *cpu_dai)
{
	struct snd_soc_component *component = cpu_dai->component;
	u32 val;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		val = PDMIC_CR_ENPDM_EN << PDMIC_CR_ENPDM_SHIFT;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		val = PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT;
		break;
	default:
		return -EINVAL;
	}

	snd_soc_component_update_bits(component, PDMIC_CR, PDMIC_CR_ENPDM_MASK, val);

	return 0;
}

static const struct snd_soc_dai_ops atmel_pdmic_cpu_dai_ops = {
	.startup	= atmel_pdmic_cpu_dai_startup,
	.shutdown	= atmel_pdmic_cpu_dai_shutdown,
	.prepare	= atmel_pdmic_cpu_dai_prepare,
	.hw_params	= atmel_pdmic_cpu_dai_hw_params,
	.trigger	= atmel_pdmic_cpu_dai_trigger,
};


static struct snd_soc_dai_driver atmel_pdmic_cpu_dai = {
	.capture = {
		.stream_name	= "Capture",
		.channels_min	= 1,
		.channels_max	= 1,
		.rates		= SNDRV_PCM_RATE_KNOT,
		.formats	= ATMEL_PDMIC_FORMATS,
	},
	.ops = &atmel_pdmic_cpu_dai_ops,
};

static const struct snd_soc_component_driver atmel_pdmic_cpu_dai_component = {
	.name			= "atmel-pdmic",
	.probe			= atmel_pdmic_component_probe,
	.controls		= atmel_pdmic_snd_controls,
	.num_controls		= ARRAY_SIZE(atmel_pdmic_snd_controls),
	.idle_bias_on		= 1,
	.use_pmdown_time	= 1,
};

/* ASoC sound card */
static int atmel_pdmic_asoc_card_init(struct device *dev,
				struct snd_soc_card *card)
{
	struct snd_soc_dai_link *dai_link;
	struct atmel_pdmic *dd = snd_soc_card_get_drvdata(card);
	struct snd_soc_dai_link_component *comp;

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

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

	dai_link->cpus		= &comp[0];
	dai_link->codecs	= &comp[1];
	dai_link->platforms	= &comp[2];

	dai_link->num_cpus	= 1;
	dai_link->num_codecs	= 1;
	dai_link->num_platforms	= 1;

	dai_link->name			= "PDMIC";
	dai_link->stream_name		= "PDMIC PCM";
	dai_link->codecs->dai_name	= "snd-soc-dummy-dai";
	dai_link->cpus->dai_name	= dev_name(dev);
	dai_link->codecs->name		= "snd-soc-dummy";
	dai_link->platforms->name	= dev_name(dev);

	card->dai_link	= dai_link;
	card->num_links	= 1;
	card->name	= dd->pdata->card_name;
	card->dev	= dev;

	return 0;
}

static void atmel_pdmic_get_sample_rate(struct atmel_pdmic *dd,
	unsigned int *rate_min, unsigned int *rate_max)
{
	u32 mic_min_freq = dd->pdata->mic_min_freq;
	u32 mic_max_freq = dd->pdata->mic_max_freq;
	u32 clk_max_rate = (u32)(clk_get_rate(dd->pclk) >> 1);
	u32 clk_min_rate = (u32)(clk_get_rate(dd->gclk) >> 8);

	if (mic_max_freq > clk_max_rate)
		mic_max_freq = clk_max_rate;

	if (mic_min_freq < clk_min_rate)
		mic_min_freq = clk_min_rate;

	*rate_min = DIV_ROUND_CLOSEST(mic_min_freq, 128);
	*rate_max = mic_max_freq >> 6;
}

/* PDMIC interrupt handler */
static irqreturn_t atmel_pdmic_interrupt(int irq, void *dev_id)
{
	struct atmel_pdmic *dd = (struct atmel_pdmic *)dev_id;
	u32 pdmic_isr;
	irqreturn_t ret = IRQ_NONE;

	regmap_read(dd->regmap, PDMIC_ISR, &pdmic_isr);

	if (pdmic_isr & PDMIC_ISR_OVRE) {
		regmap_update_bits(dd->regmap, PDMIC_CR, PDMIC_CR_ENPDM_MASK,
				   PDMIC_CR_ENPDM_DIS << PDMIC_CR_ENPDM_SHIFT);

		snd_pcm_stop_xrun(dd->substream);

		ret = IRQ_HANDLED;
	}

	return ret;
}

/* regmap configuration */
#define ATMEL_PDMIC_REG_MAX    0x124
static const struct regmap_config atmel_pdmic_regmap_config = {
	.reg_bits	= 32,
	.reg_stride	= 4,
	.val_bits	= 32,
	.max_register	= ATMEL_PDMIC_REG_MAX,
};

static int atmel_pdmic_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct atmel_pdmic *dd;
	struct resource *res;
	void __iomem *io_base;
	const struct atmel_pdmic_pdata *pdata;
	struct snd_soc_card *card;
	unsigned int rate_min, rate_max;
	int ret;

	pdata = atmel_pdmic_dt_init(dev);
	if (IS_ERR(pdata))
		return PTR_ERR(pdata);

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

	dd->pdata = pdata;
	dd->dev = dev;

	dd->irq = platform_get_irq(pdev, 0);
	if (dd->irq < 0)
		return dd->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;
	}

	/* The gclk clock frequency must always be three times
	 * lower than the pclk clock frequency
	 */
	ret = clk_set_rate(dd->gclk, clk_get_rate(dd->pclk)/3);
	if (ret) {
		dev_err(dev, "failed to set GCK clock rate: %d\n", ret);
		return ret;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	io_base = devm_ioremap_resource(dev, res);
	if (IS_ERR(io_base))
		return PTR_ERR(io_base);

	dd->phy_base = res->start;

	dd->regmap = devm_regmap_init_mmio(dev, io_base,
					   &atmel_pdmic_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, dd->irq, atmel_pdmic_interrupt, 0,
				"PDMIC", (void *)dd);
	if (ret < 0) {
		dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n",
			dd->irq, ret);
		return ret;
	}

	/* Get the minimal and maximal sample rate that the microphone supports */
	atmel_pdmic_get_sample_rate(dd, &rate_min, &rate_max);

	/* register cpu dai */
	atmel_pdmic_cpu_dai.capture.rate_min = rate_min;
	atmel_pdmic_cpu_dai.capture.rate_max = rate_max;
	ret = devm_snd_soc_register_component(dev,
					      &atmel_pdmic_cpu_dai_component,
					      &atmel_pdmic_cpu_dai, 1);
	if (ret) {
		dev_err(dev, "could not register CPU DAI: %d\n", ret);
		return ret;
	}

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

	/* register sound card */
	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
	if (!card) {
		ret = -ENOMEM;
		goto unregister_codec;
	}

	snd_soc_card_set_drvdata(card, dd);

	ret = atmel_pdmic_asoc_card_init(dev, card);
	if (ret) {
		dev_err(dev, "failed to init sound card: %d\n", ret);
		goto unregister_codec;
	}

	ret = devm_snd_soc_register_card(dev, card);
	if (ret) {
		dev_err(dev, "failed to register sound card: %d\n", ret);
		goto unregister_codec;
	}

	return 0;

unregister_codec:
	return ret;
}

static int atmel_pdmic_remove(struct platform_device *pdev)
{
	return 0;
}

static struct platform_driver atmel_pdmic_driver = {
	.driver	= {
		.name		= "atmel-pdmic",
		.of_match_table	= of_match_ptr(atmel_pdmic_of_match),
		.pm		= &snd_soc_pm_ops,
	},
	.probe	= atmel_pdmic_probe,
	.remove	= atmel_pdmic_remove,
};
module_platform_driver(atmel_pdmic_driver);

MODULE_DESCRIPTION("Atmel PDMIC driver under ALSA SoC architecture");
MODULE_AUTHOR("Songjun Wu <songjun.wu@atmel.com>");
MODULE_LICENSE("GPL v2");
