/*
 * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 * Based on sound/soc/imx/imx-pcm-dma-mx2.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.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/slab.h>
#include <linux/dmaengine.h>
#include <linux/fsl/mxs-dma.h>

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

#include "mxs-pcm.h"

struct mxs_pcm_dma_data {
	struct mxs_dma_data dma_data;
	struct mxs_pcm_dma_params *dma_params;
};

static struct snd_pcm_hardware snd_mxs_hardware = {
	.info			= SNDRV_PCM_INFO_MMAP |
				  SNDRV_PCM_INFO_MMAP_VALID |
				  SNDRV_PCM_INFO_PAUSE |
				  SNDRV_PCM_INFO_RESUME |
				  SNDRV_PCM_INFO_INTERLEAVED,
	.formats		= SNDRV_PCM_FMTBIT_S16_LE |
				  SNDRV_PCM_FMTBIT_S20_3LE |
				  SNDRV_PCM_FMTBIT_S24_LE,
	.channels_min		= 2,
	.channels_max		= 2,
	.period_bytes_min	= 32,
	.period_bytes_max	= 8192,
	.periods_min		= 1,
	.periods_max		= 52,
	.buffer_bytes_max	= 64 * 1024,
	.fifo_size		= 32,

};

static bool filter(struct dma_chan *chan, void *param)
{
	struct mxs_pcm_dma_data *pcm_dma_data = param;
	struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;

	if (!mxs_dma_is_apbx(chan))
		return false;

	if (chan->chan_id != dma_params->chan_num)
		return false;

	chan->private = &pcm_dma_data->dma_data;

	return true;
}

static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
				struct snd_pcm_hw_params *params)
{
	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	return 0;
}

static int snd_mxs_open(struct snd_pcm_substream *substream)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct mxs_pcm_dma_data *pcm_dma_data;
	int ret;

	pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
	if (pcm_dma_data == NULL)
		return -ENOMEM;

	pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;

	ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
	if (ret) {
		kfree(pcm_dma_data);
		return ret;
	}

	snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);

	snd_dmaengine_pcm_set_data(substream, pcm_dma_data);

	return 0;
}

static int snd_mxs_close(struct snd_pcm_substream *substream)
{
	struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);

	snd_dmaengine_pcm_close(substream);
	kfree(pcm_dma_data);

	return 0;
}

static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream,
		struct vm_area_struct *vma)
{
	struct snd_pcm_runtime *runtime = substream->runtime;

	return dma_mmap_writecombine(substream->pcm->card->dev, vma,
					runtime->dma_area,
					runtime->dma_addr,
					runtime->dma_bytes);
}

static struct snd_pcm_ops mxs_pcm_ops = {
	.open		= snd_mxs_open,
	.close		= snd_mxs_close,
	.ioctl		= snd_pcm_lib_ioctl,
	.hw_params	= snd_mxs_pcm_hw_params,
	.trigger	= snd_dmaengine_pcm_trigger,
	.pointer	= snd_dmaengine_pcm_pointer,
	.mmap		= snd_mxs_pcm_mmap,
};

static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
	struct snd_pcm_substream *substream = pcm->streams[stream].substream;
	struct snd_dma_buffer *buf = &substream->dma_buffer;
	size_t size = snd_mxs_hardware.buffer_bytes_max;

	buf->dev.type = SNDRV_DMA_TYPE_DEV;
	buf->dev.dev = pcm->card->dev;
	buf->private_data = NULL;
	buf->area = dma_alloc_writecombine(pcm->card->dev, size,
					   &buf->addr, GFP_KERNEL);
	if (!buf->area)
		return -ENOMEM;
	buf->bytes = size;

	return 0;
}

static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32);
static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm *pcm = rtd->pcm;
	int ret = 0;

	if (!card->dev->dma_mask)
		card->dev->dma_mask = &mxs_pcm_dmamask;
	if (!card->dev->coherent_dma_mask)
		card->dev->coherent_dma_mask = DMA_BIT_MASK(32);

	if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
		ret = mxs_pcm_preallocate_dma_buffer(pcm,
			SNDRV_PCM_STREAM_PLAYBACK);
		if (ret)
			goto out;
	}

	if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
		ret = mxs_pcm_preallocate_dma_buffer(pcm,
			SNDRV_PCM_STREAM_CAPTURE);
		if (ret)
			goto out;
	}

out:
	return ret;
}

static void mxs_pcm_free(struct snd_pcm *pcm)
{
	struct snd_pcm_substream *substream;
	struct snd_dma_buffer *buf;
	int stream;

	for (stream = 0; stream < 2; stream++) {
		substream = pcm->streams[stream].substream;
		if (!substream)
			continue;

		buf = &substream->dma_buffer;
		if (!buf->area)
			continue;

		dma_free_writecombine(pcm->card->dev, buf->bytes,
				      buf->area, buf->addr);
		buf->area = NULL;
	}
}

static struct snd_soc_platform_driver mxs_soc_platform = {
	.ops		= &mxs_pcm_ops,
	.pcm_new	= mxs_pcm_new,
	.pcm_free	= mxs_pcm_free,
};

int __devinit mxs_pcm_platform_register(struct device *dev)
{
	return snd_soc_register_platform(dev, &mxs_soc_platform);
}
EXPORT_SYMBOL_GPL(mxs_pcm_platform_register);

void __devexit mxs_pcm_platform_unregister(struct device *dev)
{
	snd_soc_unregister_platform(dev);
}
EXPORT_SYMBOL_GPL(mxs_pcm_platform_unregister);

MODULE_LICENSE("GPL");
