/*
 * ALSA PCM interface for the Stetch s6000 family
 *
 * Author:      Daniel Gloeckner, <dg@emlix.com>
 * Copyright:   (C) 2009 emlix GmbH <info@emlix.com>
 *
 * 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/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include <asm/dma.h>
#include <variant/dmac.h>

#include "s6000-pcm.h"

#define S6_PCM_PREALLOCATE_SIZE (96 * 1024)
#define S6_PCM_PREALLOCATE_MAX  (2048 * 1024)

static struct snd_pcm_hardware s6000_pcm_hardware = {
	.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
		 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
		 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX),
	.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE),
	.rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \
		  SNDRV_PCM_RATE_8000_192000),
	.rate_min = 0,
	.rate_max = 1562500,
	.channels_min = 2,
	.channels_max = 8,
	.buffer_bytes_max = 0x7ffffff0,
	.period_bytes_min = 16,
	.period_bytes_max = 0xfffff0,
	.periods_min = 2,
	.periods_max = 1024, /* no limit */
	.fifo_size = 0,
};

struct s6000_runtime_data {
	spinlock_t lock;
	int period;		/* current DMA period */
};

static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s6000_runtime_data *prtd = runtime->private_data;
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	int channel;
	unsigned int period_size;
	unsigned int dma_offset;
	dma_addr_t dma_pos;
	dma_addr_t src, dst;

	period_size = snd_pcm_lib_period_bytes(substream);
	dma_offset = prtd->period * period_size;
	dma_pos = runtime->dma_addr + dma_offset;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		src = dma_pos;
		dst = par->sif_out;
		channel = par->dma_out;
	} else {
		src = par->sif_in;
		dst = dma_pos;
		channel = par->dma_in;
	}

	if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel),
				    DMA_INDEX_CHNL(channel)))
		return;

	if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) {
		printk(KERN_ERR "s6000-pcm: fifo full\n");
		return;
	}

	BUG_ON(period_size & 15);
	s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel),
			src, dst, period_size);

	prtd->period++;
	if (unlikely(prtd->period >= runtime->periods))
		prtd->period = 0;
}

static irqreturn_t s6000_pcm_irq(int irq, void *data)
{
	struct snd_pcm *pcm = data;
	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
	struct s6000_runtime_data *prtd;
	unsigned int has_xrun;
	int i, ret = IRQ_NONE;
	u32 channel[2] = {
		[SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out,
		[SNDRV_PCM_STREAM_CAPTURE] = params->dma_in
	};

	has_xrun = params->check_xrun(runtime->dai->cpu_dai);

	for (i = 0; i < ARRAY_SIZE(channel); ++i) {
		struct snd_pcm_substream *substream = pcm->streams[i].substream;
		unsigned int pending;

		if (!channel[i])
			continue;

		if (unlikely(has_xrun & (1 << i)) &&
		    substream->runtime &&
		    snd_pcm_running(substream)) {
			dev_dbg(pcm->dev, "xrun\n");
			snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
			ret = IRQ_HANDLED;
		}

		pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]),
					     DMA_INDEX_CHNL(channel[i]));

		if (pending & 1) {
			ret = IRQ_HANDLED;
			if (likely(substream->runtime &&
				   snd_pcm_running(substream))) {
				snd_pcm_period_elapsed(substream);
				dev_dbg(pcm->dev, "period elapsed %x %x\n",
				       s6dmac_cur_src(DMA_MASK_DMAC(channel[i]),
						   DMA_INDEX_CHNL(channel[i])),
				       s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]),
						   DMA_INDEX_CHNL(channel[i])));
				prtd = substream->runtime->private_data;
				spin_lock(&prtd->lock);
				s6000_pcm_enqueue_dma(substream);
				spin_unlock(&prtd->lock);
			}
		}

		if (unlikely(pending & ~7)) {
			if (pending & (1 << 3))
				printk(KERN_WARNING
				       "s6000-pcm: DMA %x Underflow\n",
				       channel[i]);
			if (pending & (1 << 4))
				printk(KERN_WARNING
				       "s6000-pcm: DMA %x Overflow\n",
				       channel[i]);
			if (pending & 0x1e0)
				printk(KERN_WARNING
				       "s6000-pcm: DMA %x Master Error "
				       "(mask %x)\n",
				       channel[i], pending >> 5);

		}
	}

	return ret;
}

static int s6000_pcm_start(struct snd_pcm_substream *substream)
{
	struct s6000_runtime_data *prtd = substream->runtime->private_data;
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	unsigned long flags;
	int srcinc;
	u32 dma;

	spin_lock_irqsave(&prtd->lock, flags);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		srcinc = 1;
		dma = par->dma_out;
	} else {
		srcinc = 0;
		dma = par->dma_in;
	}
	s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma),
			   1 /* priority 1 (0 is max) */,
			   0 /* peripheral requests w/o xfer length mode */,
			   srcinc /* source address increment */,
			   srcinc^1 /* destination address increment */,
			   0 /* chunksize 0 (skip impossible on this dma) */,
			   0 /* source skip after chunk (impossible) */,
			   0 /* destination skip after chunk (impossible) */,
			   4 /* 16 byte burst size */,
			   -1 /* don't conserve bandwidth */,
			   0 /* low watermark irq descriptor theshold */,
			   0 /* disable hardware timestamps */,
			   1 /* enable channel */);

	s6000_pcm_enqueue_dma(substream);
	s6000_pcm_enqueue_dma(substream);

	spin_unlock_irqrestore(&prtd->lock, flags);

	return 0;
}

static int s6000_pcm_stop(struct snd_pcm_substream *substream)
{
	struct s6000_runtime_data *prtd = substream->runtime->private_data;
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	unsigned long flags;
	u32 channel;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		channel = par->dma_out;
	else
		channel = par->dma_in;

	s6dmac_set_terminal_count(DMA_MASK_DMAC(channel),
				  DMA_INDEX_CHNL(channel), 0);

	spin_lock_irqsave(&prtd->lock, flags);

	s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel));

	spin_unlock_irqrestore(&prtd->lock, flags);

	return 0;
}

static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	int ret;

	ret = par->trigger(substream, cmd, 0);
	if (ret < 0)
		return ret;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		ret = s6000_pcm_start(substream);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		ret = s6000_pcm_stop(substream);
		break;
	default:
		ret = -EINVAL;
	}
	if (ret < 0)
		return ret;

	return par->trigger(substream, cmd, 1);
}

static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
{
	struct s6000_runtime_data *prtd = substream->runtime->private_data;

	prtd->period = 0;

	return 0;
}

static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s6000_runtime_data *prtd = runtime->private_data;
	unsigned long flags;
	unsigned int offset;
	dma_addr_t count;

	spin_lock_irqsave(&prtd->lock, flags);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out),
				       DMA_INDEX_CHNL(par->dma_out));
	else
		count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in),
				       DMA_INDEX_CHNL(par->dma_in));

	count -= runtime->dma_addr;

	spin_unlock_irqrestore(&prtd->lock, flags);

	offset = bytes_to_frames(runtime, count);
	if (unlikely(offset >= runtime->buffer_size))
		offset = 0;

	return offset;
}

static int s6000_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s6000_runtime_data *prtd;
	int ret;

	snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);

	ret = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16);
	if (ret < 0)
		return ret;
	ret = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16);
	if (ret < 0)
		return ret;
	ret = snd_pcm_hw_constraint_integer(runtime,
					    SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		return ret;

	if (par->same_rate) {
		int rate;
		spin_lock(&par->lock); /* needed? */
		rate = par->rate;
		spin_unlock(&par->lock);
		if (rate != -1) {
			ret = snd_pcm_hw_constraint_minmax(runtime,
							SNDRV_PCM_HW_PARAM_RATE,
							rate, rate);
			if (ret < 0)
				return ret;
		}
	}

	prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL);
	if (prtd == NULL)
		return -ENOMEM;

	spin_lock_init(&prtd->lock);

	runtime->private_data = prtd;

	return 0;
}

static int s6000_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct s6000_runtime_data *prtd = runtime->private_data;

	kfree(prtd);

	return 0;
}

static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
				 struct snd_pcm_hw_params *hw_params)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;
	int ret;
	ret = snd_pcm_lib_malloc_pages(substream,
				       params_buffer_bytes(hw_params));
	if (ret < 0) {
		printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n");
		return ret;
	}

	if (par->same_rate) {
		spin_lock(&par->lock);
		if (par->rate == -1 ||
		    !(par->in_use & ~(1 << substream->stream))) {
			par->rate = params_rate(hw_params);
			par->in_use |= 1 << substream->stream;
		} else if (params_rate(hw_params) != par->rate) {
			snd_pcm_lib_free_pages(substream);
			par->in_use &= ~(1 << substream->stream);
			ret = -EBUSY;
		}
		spin_unlock(&par->lock);
	}
	return ret;
}

static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
	struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data;

	spin_lock(&par->lock);
	par->in_use &= ~(1 << substream->stream);
	if (!par->in_use)
		par->rate = -1;
	spin_unlock(&par->lock);

	return snd_pcm_lib_free_pages(substream);
}

static struct snd_pcm_ops s6000_pcm_ops = {
	.open = 	s6000_pcm_open,
	.close = 	s6000_pcm_close,
	.ioctl = 	snd_pcm_lib_ioctl,
	.hw_params = 	s6000_pcm_hw_params,
	.hw_free = 	s6000_pcm_hw_free,
	.trigger =	s6000_pcm_trigger,
	.prepare = 	s6000_pcm_prepare,
	.pointer = 	s6000_pcm_pointer,
};

static void s6000_pcm_free(struct snd_pcm *pcm)
{
	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;

	free_irq(params->irq, pcm);
	snd_pcm_lib_preallocate_free_for_all(pcm);
}

static u64 s6000_pcm_dmamask = DMA_32BIT_MASK;

static int s6000_pcm_new(struct snd_card *card,
			 struct snd_soc_dai *dai, struct snd_pcm *pcm)
{
	struct snd_soc_pcm_runtime *runtime = pcm->private_data;
	struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data;
	int res;

	if (!card->dev->dma_mask)
		card->dev->dma_mask = &s6000_pcm_dmamask;
	if (!card->dev->coherent_dma_mask)
		card->dev->coherent_dma_mask = DMA_32BIT_MASK;

	if (params->dma_in) {
		s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
				    DMA_INDEX_CHNL(params->dma_in));
		s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in),
				   DMA_INDEX_CHNL(params->dma_in));
	}

	if (params->dma_out) {
		s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out),
				    DMA_INDEX_CHNL(params->dma_out));
		s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out),
				   DMA_INDEX_CHNL(params->dma_out));
	}

	res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED,
			  s6000_soc_platform.name, pcm);
	if (res) {
		printk(KERN_ERR "s6000-pcm couldn't get IRQ\n");
		return res;
	}

	res = snd_pcm_lib_preallocate_pages_for_all(pcm,
						    SNDRV_DMA_TYPE_DEV,
						    card->dev,
						    S6_PCM_PREALLOCATE_SIZE,
						    S6_PCM_PREALLOCATE_MAX);
	if (res)
		printk(KERN_WARNING "s6000-pcm: preallocation failed\n");

	spin_lock_init(&params->lock);
	params->in_use = 0;
	params->rate = -1;
	return 0;
}

struct snd_soc_platform s6000_soc_platform = {
	.name = 	"s6000-audio",
	.pcm_ops = 	&s6000_pcm_ops,
	.pcm_new = 	s6000_pcm_new,
	.pcm_free = 	s6000_pcm_free,
};
EXPORT_SYMBOL_GPL(s6000_soc_platform);

static int __init s6000_pcm_init(void)
{
	return snd_soc_register_platform(&s6000_soc_platform);
}
module_init(s6000_pcm_init);

static void __exit s6000_pcm_exit(void)
{
	snd_soc_unregister_platform(&s6000_soc_platform);
}
module_exit(s6000_pcm_exit);

MODULE_AUTHOR("Daniel Gloeckner");
MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module");
MODULE_LICENSE("GPL");
