// SPDX-License-Identifier: GPL-2.0-only
/*
 * Au1000/Au1500/Au1100 I2S controller driver for ASoC
 *
 * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
 *
 * Note: clock supplied to the I2S controller must be 256x samplerate.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/suspend.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include <asm/mach-au1x00/au1000.h>

#include "psc.h"

#define I2S_RXTX	0x00
#define I2S_CFG		0x04
#define I2S_ENABLE	0x08

#define CFG_XU		(1 << 25)	/* tx underflow */
#define CFG_XO		(1 << 24)
#define CFG_RU		(1 << 23)
#define CFG_RO		(1 << 22)
#define CFG_TR		(1 << 21)
#define CFG_TE		(1 << 20)
#define CFG_TF		(1 << 19)
#define CFG_RR		(1 << 18)
#define CFG_RF		(1 << 17)
#define CFG_ICK		(1 << 12)	/* clock invert */
#define CFG_PD		(1 << 11)	/* set to make I2SDIO INPUT */
#define CFG_LB		(1 << 10)	/* loopback */
#define CFG_IC		(1 << 9)	/* word select invert */
#define CFG_FM_I2S	(0 << 7)	/* I2S format */
#define CFG_FM_LJ	(1 << 7)	/* left-justified */
#define CFG_FM_RJ	(2 << 7)	/* right-justified */
#define CFG_FM_MASK	(3 << 7)
#define CFG_TN		(1 << 6)	/* tx fifo en */
#define CFG_RN		(1 << 5)	/* rx fifo en */
#define CFG_SZ_8	(0x08)
#define CFG_SZ_16	(0x10)
#define CFG_SZ_18	(0x12)
#define CFG_SZ_20	(0x14)
#define CFG_SZ_24	(0x18)
#define CFG_SZ_MASK	(0x1f)
#define EN_D		(1 << 1)	/* DISable */
#define EN_CE		(1 << 0)	/* clock enable */

/* only limited by clock generator and board design */
#define AU1XI2SC_RATES \
	SNDRV_PCM_RATE_CONTINUOUS

#define AU1XI2SC_FMTS \
	(SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |		\
	SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |	\
	SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE |	\
	SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE |	\
	SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE |	\
	SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE |	\
	SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE |	\
	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |	\
	SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE |	\
	0)

static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg)
{
	return __raw_readl(ctx->mmio + reg);
}

static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v)
{
	__raw_writel(v, ctx->mmio + reg);
	wmb();
}

static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
{
	struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai);
	unsigned long c;
	int ret;

	ret = -EINVAL;
	c = ctx->cfg;

	c &= ~CFG_FM_MASK;
	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
	case SND_SOC_DAIFMT_I2S:
		c |= CFG_FM_I2S;
		break;
	case SND_SOC_DAIFMT_MSB:
		c |= CFG_FM_RJ;
		break;
	case SND_SOC_DAIFMT_LSB:
		c |= CFG_FM_LJ;
		break;
	default:
		goto out;
	}

	c &= ~(CFG_IC | CFG_ICK);		/* IB-IF */
	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
	case SND_SOC_DAIFMT_NB_NF:
		c |= CFG_IC | CFG_ICK;
		break;
	case SND_SOC_DAIFMT_NB_IF:
		c |= CFG_IC;
		break;
	case SND_SOC_DAIFMT_IB_NF:
		c |= CFG_ICK;
		break;
	case SND_SOC_DAIFMT_IB_IF:
		break;
	default:
		goto out;
	}

	/* I2S controller only supports provider */
	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
	case SND_SOC_DAIFMT_BP_FP:	/* CODEC consumer */
		break;
	default:
		goto out;
	}

	ret = 0;
	ctx->cfg = c;
out:
	return ret;
}

static int au1xi2s_trigger(struct snd_pcm_substream *substream,
			   int cmd, struct snd_soc_dai *dai)
{
	struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
	int stype = SUBSTREAM_TYPE(substream);

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
		/* power up */
		WR(ctx, I2S_ENABLE, EN_D | EN_CE);
		WR(ctx, I2S_ENABLE, EN_CE);
		ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN;
		WR(ctx, I2S_CFG, ctx->cfg);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN);
		WR(ctx, I2S_CFG, ctx->cfg);
		WR(ctx, I2S_ENABLE, EN_D);		/* power off */
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static unsigned long msbits_to_reg(int msbits)
{
	switch (msbits) {
	case 8:
		return CFG_SZ_8;
	case 16:
		return CFG_SZ_16;
	case 18:
		return CFG_SZ_18;
	case 20:
		return CFG_SZ_20;
	case 24:
		return CFG_SZ_24;
	}
	return 0;
}

static int au1xi2s_hw_params(struct snd_pcm_substream *substream,
			     struct snd_pcm_hw_params *params,
			     struct snd_soc_dai *dai)
{
	struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
	unsigned long v;

	v = msbits_to_reg(params->msbits);
	if (!v)
		return -EINVAL;

	ctx->cfg &= ~CFG_SZ_MASK;
	ctx->cfg |= v;
	return 0;
}

static int au1xi2s_startup(struct snd_pcm_substream *substream,
			   struct snd_soc_dai *dai)
{
	struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai);
	snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]);
	return 0;
}

static const struct snd_soc_dai_ops au1xi2s_dai_ops = {
	.startup	= au1xi2s_startup,
	.trigger	= au1xi2s_trigger,
	.hw_params	= au1xi2s_hw_params,
	.set_fmt	= au1xi2s_set_fmt,
};

static struct snd_soc_dai_driver au1xi2s_dai_driver = {
	.symmetric_rate		= 1,
	.playback = {
		.rates		= AU1XI2SC_RATES,
		.formats	= AU1XI2SC_FMTS,
		.channels_min	= 2,
		.channels_max	= 2,
	},
	.capture = {
		.rates		= AU1XI2SC_RATES,
		.formats	= AU1XI2SC_FMTS,
		.channels_min	= 2,
		.channels_max	= 2,
	},
	.ops = &au1xi2s_dai_ops,
};

static const struct snd_soc_component_driver au1xi2s_component = {
	.name			= "au1xi2s",
	.legacy_dai_naming	= 1,
};

static int au1xi2s_drvprobe(struct platform_device *pdev)
{
	struct resource *iores, *dmares;
	struct au1xpsc_audio_data *ctx;

	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iores)
		return -ENODEV;

	if (!devm_request_mem_region(&pdev->dev, iores->start,
				     resource_size(iores),
				     pdev->name))
		return -EBUSY;

	ctx->mmio = devm_ioremap(&pdev->dev, iores->start,
					 resource_size(iores));
	if (!ctx->mmio)
		return -EBUSY;

	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
	if (!dmares)
		return -EBUSY;
	ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start;

	dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1);
	if (!dmares)
		return -EBUSY;
	ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start;

	platform_set_drvdata(pdev, ctx);

	return snd_soc_register_component(&pdev->dev, &au1xi2s_component,
					  &au1xi2s_dai_driver, 1);
}

static void au1xi2s_drvremove(struct platform_device *pdev)
{
	struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev);

	snd_soc_unregister_component(&pdev->dev);

	WR(ctx, I2S_ENABLE, EN_D);	/* clock off, disable */
}

#ifdef CONFIG_PM
static int au1xi2s_drvsuspend(struct device *dev)
{
	struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev);

	WR(ctx, I2S_ENABLE, EN_D);	/* clock off, disable */

	return 0;
}

static int au1xi2s_drvresume(struct device *dev)
{
	return 0;
}

static const struct dev_pm_ops au1xi2sc_pmops = {
	.suspend	= au1xi2s_drvsuspend,
	.resume		= au1xi2s_drvresume,
};

#define AU1XI2SC_PMOPS (&au1xi2sc_pmops)

#else

#define AU1XI2SC_PMOPS NULL

#endif

static struct platform_driver au1xi2s_driver = {
	.driver	= {
		.name	= "alchemy-i2sc",
		.pm	= AU1XI2SC_PMOPS,
	},
	.probe		= au1xi2s_drvprobe,
	.remove_new	= au1xi2s_drvremove,
};

module_platform_driver(au1xi2s_driver);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver");
MODULE_AUTHOR("Manuel Lauss");
