/*
 * Driver for the Atmel on-chip Audio Bitstream DAC (ABDAC)
 *
 * Copyright (C) 2006-2009 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 */
#include <linux/clk.h>
#include <linux/bitmap.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/io.h>

#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/atmel-abdac.h>

#include <linux/platform_data/dma-dw.h>
#include <linux/dma/dw.h>

/* DAC register offsets */
#define DAC_DATA                                0x0000
#define DAC_CTRL                                0x0008
#define DAC_INT_MASK                            0x000c
#define DAC_INT_EN                              0x0010
#define DAC_INT_DIS                             0x0014
#define DAC_INT_CLR                             0x0018
#define DAC_INT_STATUS                          0x001c

/* Bitfields in CTRL */
#define DAC_SWAP_OFFSET                         30
#define DAC_SWAP_SIZE                           1
#define DAC_EN_OFFSET                           31
#define DAC_EN_SIZE                             1

/* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */
#define DAC_UNDERRUN_OFFSET                     28
#define DAC_UNDERRUN_SIZE                       1
#define DAC_TX_READY_OFFSET                     29
#define DAC_TX_READY_SIZE                       1

/* Bit manipulation macros */
#define DAC_BIT(name)					\
	(1 << DAC_##name##_OFFSET)
#define DAC_BF(name, value)				\
	(((value) & ((1 << DAC_##name##_SIZE) - 1))	\
	 << DAC_##name##_OFFSET)
#define DAC_BFEXT(name, value)				\
	(((value) >> DAC_##name##_OFFSET)		\
	 & ((1 << DAC_##name##_SIZE) - 1))
#define DAC_BFINS(name, value, old)			\
	(((old) & ~(((1 << DAC_##name##_SIZE) - 1)	\
		    << DAC_##name##_OFFSET))		\
	 | DAC_BF(name, value))

/* Register access macros */
#define dac_readl(port, reg)				\
	__raw_readl((port)->regs + DAC_##reg)
#define dac_writel(port, reg, value)			\
	__raw_writel((value), (port)->regs + DAC_##reg)

/*
 * ABDAC supports a maximum of 6 different rates from a generic clock. The
 * generic clock has a power of two divider, which gives 6 steps from 192 kHz
 * to 5112 Hz.
 */
#define MAX_NUM_RATES	6
/* ALSA seems to use rates between 192000 Hz and 5112 Hz. */
#define RATE_MAX	192000
#define RATE_MIN	5112

enum {
	DMA_READY = 0,
};

struct atmel_abdac_dma {
	struct dma_chan		*chan;
	struct dw_cyclic_desc	*cdesc;
};

struct atmel_abdac {
	struct clk				*pclk;
	struct clk				*sample_clk;
	struct platform_device			*pdev;
	struct atmel_abdac_dma			dma;

	struct snd_pcm_hw_constraint_list	constraints_rates;
	struct snd_pcm_substream		*substream;
	struct snd_card				*card;
	struct snd_pcm				*pcm;

	void __iomem				*regs;
	unsigned long				flags;
	unsigned int				rates[MAX_NUM_RATES];
	unsigned int				rates_num;
	int					irq;
};

#define get_dac(card) ((struct atmel_abdac *)(card)->private_data)

/* This function is called by the DMA driver. */
static void atmel_abdac_dma_period_done(void *arg)
{
	struct atmel_abdac *dac = arg;
	snd_pcm_period_elapsed(dac->substream);
}

static int atmel_abdac_prepare_dma(struct atmel_abdac *dac,
		struct snd_pcm_substream *substream,
		enum dma_data_direction direction)
{
	struct dma_chan			*chan = dac->dma.chan;
	struct dw_cyclic_desc		*cdesc;
	struct snd_pcm_runtime		*runtime = substream->runtime;
	unsigned long			buffer_len, period_len;

	/*
	 * We don't do DMA on "complex" transfers, i.e. with
	 * non-halfword-aligned buffers or lengths.
	 */
	if (runtime->dma_addr & 1 || runtime->buffer_size & 1) {
		dev_dbg(&dac->pdev->dev, "too complex transfer\n");
		return -EINVAL;
	}

	buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
	period_len = frames_to_bytes(runtime, runtime->period_size);

	cdesc = dw_dma_cyclic_prep(chan, runtime->dma_addr, buffer_len,
			period_len, DMA_MEM_TO_DEV);
	if (IS_ERR(cdesc)) {
		dev_dbg(&dac->pdev->dev, "could not prepare cyclic DMA\n");
		return PTR_ERR(cdesc);
	}

	cdesc->period_callback = atmel_abdac_dma_period_done;
	cdesc->period_callback_param = dac;

	dac->dma.cdesc = cdesc;

	set_bit(DMA_READY, &dac->flags);

	return 0;
}

static struct snd_pcm_hardware atmel_abdac_hw = {
	.info			= (SNDRV_PCM_INFO_MMAP
				  | SNDRV_PCM_INFO_MMAP_VALID
				  | SNDRV_PCM_INFO_INTERLEAVED
				  | SNDRV_PCM_INFO_BLOCK_TRANSFER
				  | SNDRV_PCM_INFO_RESUME
				  | SNDRV_PCM_INFO_PAUSE),
	.formats		= (SNDRV_PCM_FMTBIT_S16_BE),
	.rates			= (SNDRV_PCM_RATE_KNOT),
	.rate_min		= RATE_MIN,
	.rate_max		= RATE_MAX,
	.channels_min		= 2,
	.channels_max		= 2,
	.buffer_bytes_max	= 64 * 4096,
	.period_bytes_min	= 4096,
	.period_bytes_max	= 4096,
	.periods_min		= 6,
	.periods_max		= 64,
};

static int atmel_abdac_open(struct snd_pcm_substream *substream)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);

	dac->substream = substream;
	atmel_abdac_hw.rate_max = dac->rates[dac->rates_num - 1];
	atmel_abdac_hw.rate_min = dac->rates[0];
	substream->runtime->hw = atmel_abdac_hw;

	return snd_pcm_hw_constraint_list(substream->runtime, 0,
			SNDRV_PCM_HW_PARAM_RATE, &dac->constraints_rates);
}

static int atmel_abdac_close(struct snd_pcm_substream *substream)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
	dac->substream = NULL;
	return 0;
}

static int atmel_abdac_hw_params(struct snd_pcm_substream *substream,
		struct snd_pcm_hw_params *hw_params)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
	int retval;

	retval = snd_pcm_lib_malloc_pages(substream,
			params_buffer_bytes(hw_params));
	if (retval < 0)
		return retval;
	/* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */
	if (retval == 1)
		if (test_and_clear_bit(DMA_READY, &dac->flags))
			dw_dma_cyclic_free(dac->dma.chan);

	return retval;
}

static int atmel_abdac_hw_free(struct snd_pcm_substream *substream)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
	if (test_and_clear_bit(DMA_READY, &dac->flags))
		dw_dma_cyclic_free(dac->dma.chan);
	return snd_pcm_lib_free_pages(substream);
}

static int atmel_abdac_prepare(struct snd_pcm_substream *substream)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
	int retval;

	retval = clk_set_rate(dac->sample_clk, 256 * substream->runtime->rate);
	if (retval)
		return retval;

	if (!test_bit(DMA_READY, &dac->flags))
		retval = atmel_abdac_prepare_dma(dac, substream, DMA_TO_DEVICE);

	return retval;
}

static int atmel_abdac_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct atmel_abdac *dac = snd_pcm_substream_chip(substream);
	int retval = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */
	case SNDRV_PCM_TRIGGER_RESUME: /* fall through */
	case SNDRV_PCM_TRIGGER_START:
		clk_prepare_enable(dac->sample_clk);
		retval = dw_dma_cyclic_start(dac->dma.chan);
		if (retval)
			goto out;
		dac_writel(dac, CTRL, DAC_BIT(EN));
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */
	case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */
	case SNDRV_PCM_TRIGGER_STOP:
		dw_dma_cyclic_stop(dac->dma.chan);
		dac_writel(dac, DATA, 0);
		dac_writel(dac, CTRL, 0);
		clk_disable_unprepare(dac->sample_clk);
		break;
	default:
		retval = -EINVAL;
		break;
	}
out:
	return retval;
}

static snd_pcm_uframes_t
atmel_abdac_pointer(struct snd_pcm_substream *substream)
{
	struct atmel_abdac	*dac = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime	*runtime = substream->runtime;
	snd_pcm_uframes_t	frames;
	unsigned long		bytes;

	bytes = dw_dma_get_src_addr(dac->dma.chan);
	bytes -= runtime->dma_addr;

	frames = bytes_to_frames(runtime, bytes);
	if (frames >= runtime->buffer_size)
		frames -= runtime->buffer_size;

	return frames;
}

static irqreturn_t abdac_interrupt(int irq, void *dev_id)
{
	struct atmel_abdac *dac = dev_id;
	u32 status;

	status = dac_readl(dac, INT_STATUS);
	if (status & DAC_BIT(UNDERRUN)) {
		dev_err(&dac->pdev->dev, "underrun detected\n");
		dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN));
	} else {
		dev_err(&dac->pdev->dev, "spurious interrupt (status=0x%x)\n",
			status);
		dac_writel(dac, INT_CLR, status);
	}

	return IRQ_HANDLED;
}

static struct snd_pcm_ops atmel_abdac_ops = {
	.open		= atmel_abdac_open,
	.close		= atmel_abdac_close,
	.ioctl		= snd_pcm_lib_ioctl,
	.hw_params	= atmel_abdac_hw_params,
	.hw_free	= atmel_abdac_hw_free,
	.prepare	= atmel_abdac_prepare,
	.trigger	= atmel_abdac_trigger,
	.pointer	= atmel_abdac_pointer,
};

static int atmel_abdac_pcm_new(struct atmel_abdac *dac)
{
	struct snd_pcm_hardware hw = atmel_abdac_hw;
	struct snd_pcm *pcm;
	int retval;

	retval = snd_pcm_new(dac->card, dac->card->shortname,
			dac->pdev->id, 1, 0, &pcm);
	if (retval)
		return retval;

	strcpy(pcm->name, dac->card->shortname);
	pcm->private_data = dac;
	pcm->info_flags = 0;
	dac->pcm = pcm;

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &atmel_abdac_ops);

	retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
			&dac->pdev->dev, hw.periods_min * hw.period_bytes_min,
			hw.buffer_bytes_max);

	return retval;
}

static bool filter(struct dma_chan *chan, void *slave)
{
	struct dw_dma_slave *dws = slave;

	if (dws->dma_dev == chan->device->dev) {
		chan->private = dws;
		return true;
	} else
		return false;
}

static int set_sample_rates(struct atmel_abdac *dac)
{
	long new_rate = RATE_MAX;
	int retval = -EINVAL;
	int index = 0;

	/* we start at 192 kHz and work our way down to 5112 Hz */
	while (new_rate >= RATE_MIN && index < (MAX_NUM_RATES + 1)) {
		new_rate = clk_round_rate(dac->sample_clk, 256 * new_rate);
		if (new_rate <= 0)
			break;
		/* make sure we are below the ABDAC clock */
		if (index < MAX_NUM_RATES &&
		    new_rate <= clk_get_rate(dac->pclk)) {
			dac->rates[index] = new_rate / 256;
			index++;
		}
		/* divide by 256 and then by two to get next rate */
		new_rate /= 256 * 2;
	}

	if (index) {
		int i;

		/* reverse array, smallest go first */
		for (i = 0; i < (index / 2); i++) {
			unsigned int tmp = dac->rates[index - 1 - i];
			dac->rates[index - 1 - i] = dac->rates[i];
			dac->rates[i] = tmp;
		}

		dac->constraints_rates.count = index;
		dac->constraints_rates.list = dac->rates;
		dac->constraints_rates.mask = 0;
		dac->rates_num = index;

		retval = 0;
	}

	return retval;
}

static int atmel_abdac_probe(struct platform_device *pdev)
{
	struct snd_card		*card;
	struct atmel_abdac	*dac;
	struct resource		*regs;
	struct atmel_abdac_pdata	*pdata;
	struct clk		*pclk;
	struct clk		*sample_clk;
	int			retval;
	int			irq;

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!regs) {
		dev_dbg(&pdev->dev, "no memory resource\n");
		return -ENXIO;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_dbg(&pdev->dev, "could not get IRQ number\n");
		return irq;
	}

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_dbg(&pdev->dev, "no platform data\n");
		return -ENXIO;
	}

	pclk = clk_get(&pdev->dev, "pclk");
	if (IS_ERR(pclk)) {
		dev_dbg(&pdev->dev, "no peripheral clock\n");
		return PTR_ERR(pclk);
	}
	sample_clk = clk_get(&pdev->dev, "sample_clk");
	if (IS_ERR(sample_clk)) {
		dev_dbg(&pdev->dev, "no sample clock\n");
		retval = PTR_ERR(sample_clk);
		goto out_put_pclk;
	}
	clk_prepare_enable(pclk);

	retval = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1,
			      SNDRV_DEFAULT_STR1, THIS_MODULE,
			      sizeof(struct atmel_abdac), &card);
	if (retval) {
		dev_dbg(&pdev->dev, "could not create sound card device\n");
		goto out_put_sample_clk;
	}

	dac = get_dac(card);

	dac->irq = irq;
	dac->card = card;
	dac->pclk = pclk;
	dac->sample_clk = sample_clk;
	dac->pdev = pdev;

	retval = set_sample_rates(dac);
	if (retval < 0) {
		dev_dbg(&pdev->dev, "could not set supported rates\n");
		goto out_free_card;
	}

	dac->regs = ioremap(regs->start, resource_size(regs));
	if (!dac->regs) {
		dev_dbg(&pdev->dev, "could not remap register memory\n");
		retval = -ENOMEM;
		goto out_free_card;
	}

	/* make sure the DAC is silent and disabled */
	dac_writel(dac, DATA, 0);
	dac_writel(dac, CTRL, 0);

	retval = request_irq(irq, abdac_interrupt, 0, "abdac", dac);
	if (retval) {
		dev_dbg(&pdev->dev, "could not request irq\n");
		goto out_unmap_regs;
	}

	if (pdata->dws.dma_dev) {
		dma_cap_mask_t mask;

		dma_cap_zero(mask);
		dma_cap_set(DMA_SLAVE, mask);

		dac->dma.chan = dma_request_channel(mask, filter, &pdata->dws);
		if (dac->dma.chan) {
			struct dma_slave_config dma_conf = {
				.dst_addr = regs->start + DAC_DATA,
				.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
				.src_maxburst = 1,
				.dst_maxburst = 1,
				.direction = DMA_MEM_TO_DEV,
				.device_fc = false,
			};

			dmaengine_slave_config(dac->dma.chan, &dma_conf);
		}
	}
	if (!pdata->dws.dma_dev || !dac->dma.chan) {
		dev_dbg(&pdev->dev, "DMA not available\n");
		retval = -ENODEV;
		goto out_unmap_regs;
	}

	strcpy(card->driver, "Atmel ABDAC");
	strcpy(card->shortname, "Atmel ABDAC");
	sprintf(card->longname, "Atmel Audio Bitstream DAC");

	retval = atmel_abdac_pcm_new(dac);
	if (retval) {
		dev_dbg(&pdev->dev, "could not register ABDAC pcm device\n");
		goto out_release_dma;
	}

	retval = snd_card_register(card);
	if (retval) {
		dev_dbg(&pdev->dev, "could not register sound card\n");
		goto out_release_dma;
	}

	platform_set_drvdata(pdev, card);

	dev_info(&pdev->dev, "Atmel ABDAC at 0x%p using %s\n",
			dac->regs, dev_name(&dac->dma.chan->dev->device));

	return retval;

out_release_dma:
	dma_release_channel(dac->dma.chan);
	dac->dma.chan = NULL;
out_unmap_regs:
	iounmap(dac->regs);
out_free_card:
	snd_card_free(card);
out_put_sample_clk:
	clk_put(sample_clk);
	clk_disable_unprepare(pclk);
out_put_pclk:
	clk_put(pclk);
	return retval;
}

#ifdef CONFIG_PM_SLEEP
static int atmel_abdac_suspend(struct device *pdev)
{
	struct snd_card *card = dev_get_drvdata(pdev);
	struct atmel_abdac *dac = card->private_data;

	dw_dma_cyclic_stop(dac->dma.chan);
	clk_disable_unprepare(dac->sample_clk);
	clk_disable_unprepare(dac->pclk);

	return 0;
}

static int atmel_abdac_resume(struct device *pdev)
{
	struct snd_card *card = dev_get_drvdata(pdev);
	struct atmel_abdac *dac = card->private_data;

	clk_prepare_enable(dac->pclk);
	clk_prepare_enable(dac->sample_clk);
	if (test_bit(DMA_READY, &dac->flags))
		dw_dma_cyclic_start(dac->dma.chan);

	return 0;
}

static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
#define ATMEL_ABDAC_PM_OPS	&atmel_abdac_pm
#else
#define ATMEL_ABDAC_PM_OPS	NULL
#endif

static int atmel_abdac_remove(struct platform_device *pdev)
{
	struct snd_card *card = platform_get_drvdata(pdev);
	struct atmel_abdac *dac = get_dac(card);

	clk_put(dac->sample_clk);
	clk_disable_unprepare(dac->pclk);
	clk_put(dac->pclk);

	dma_release_channel(dac->dma.chan);
	dac->dma.chan = NULL;
	iounmap(dac->regs);
	free_irq(dac->irq, dac);
	snd_card_free(card);

	return 0;
}

static struct platform_driver atmel_abdac_driver = {
	.remove		= atmel_abdac_remove,
	.driver		= {
		.name	= "atmel_abdac",
		.pm	= ATMEL_ABDAC_PM_OPS,
	},
};

static int __init atmel_abdac_init(void)
{
	return platform_driver_probe(&atmel_abdac_driver,
			atmel_abdac_probe);
}
module_init(atmel_abdac_init);

static void __exit atmel_abdac_exit(void)
{
	platform_driver_unregister(&atmel_abdac_driver);
}
module_exit(atmel_abdac_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Driver for Atmel Audio Bitstream DAC (ABDAC)");
MODULE_AUTHOR("Hans-Christian Egtvedt <egtvedt@samfundet.no>");
