// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2019 Spreadtrum Communications Inc.

#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/dma/sprd-dma.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>

#include "sprd-pcm-dma.h"

#define DRV_NAME			"sprd_pcm_dma"
#define SPRD_PCM_DMA_LINKLIST_SIZE	64
#define SPRD_PCM_DMA_BRUST_LEN		640

struct sprd_pcm_dma_data {
	struct dma_chan *chan;
	struct dma_async_tx_descriptor *desc;
	dma_cookie_t cookie;
	dma_addr_t phys;
	void *virt;
	int pre_pointer;
};

struct sprd_pcm_dma_private {
	struct snd_pcm_substream *substream;
	struct sprd_pcm_dma_params *params;
	struct sprd_pcm_dma_data data[SPRD_PCM_CHANNEL_MAX];
	int hw_chan;
	int dma_addr_offset;
};

static const struct snd_pcm_hardware sprd_pcm_hardware = {
	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
		SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE |
		SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
	.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
	.period_bytes_min = 1,
	.period_bytes_max = 64 * 1024,
	.periods_min = 1,
	.periods_max = PAGE_SIZE / SPRD_PCM_DMA_LINKLIST_SIZE,
	.buffer_bytes_max = 64 * 1024,
};

static int sprd_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	struct device *dev = component->dev;
	struct sprd_pcm_dma_private *dma_private;
	int hw_chan = SPRD_PCM_CHANNEL_MAX;
	int size, ret, i;

	snd_soc_set_runtime_hwparams(substream, &sprd_pcm_hardware);

	ret = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
					 SPRD_PCM_DMA_BRUST_LEN);
	if (ret < 0)
		return ret;

	ret = snd_pcm_hw_constraint_step(runtime, 0,
					 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
					 SPRD_PCM_DMA_BRUST_LEN);
	if (ret < 0)
		return ret;

	ret = snd_pcm_hw_constraint_integer(runtime,
					    SNDRV_PCM_HW_PARAM_PERIODS);
	if (ret < 0)
		return ret;

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

	size = runtime->hw.periods_max * SPRD_PCM_DMA_LINKLIST_SIZE;

	for (i = 0; i < hw_chan; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		data->virt = dmam_alloc_coherent(dev, size, &data->phys,
						 GFP_KERNEL);
		if (!data->virt) {
			ret = -ENOMEM;
			goto error;
		}
	}

	dma_private->hw_chan = hw_chan;
	runtime->private_data = dma_private;
	dma_private->substream = substream;

	return 0;

error:
	for (i = 0; i < hw_chan; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		if (data->virt)
			dmam_free_coherent(dev, size, data->virt, data->phys);
	}

	devm_kfree(dev, dma_private);
	return ret;
}

static int sprd_pcm_close(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct sprd_pcm_dma_private *dma_private = runtime->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	struct device *dev = component->dev;
	int size = runtime->hw.periods_max * SPRD_PCM_DMA_LINKLIST_SIZE;
	int i;

	for (i = 0; i < dma_private->hw_chan; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		dmam_free_coherent(dev, size, data->virt, data->phys);
	}

	devm_kfree(dev, dma_private);

	return 0;
}

static void sprd_pcm_dma_complete(void *data)
{
	struct sprd_pcm_dma_private *dma_private = data;
	struct snd_pcm_substream *substream = dma_private->substream;

	snd_pcm_period_elapsed(substream);
}

static void sprd_pcm_release_dma_channel(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sprd_pcm_dma_private *dma_private = runtime->private_data;
	int i;

	for (i = 0; i < SPRD_PCM_CHANNEL_MAX; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		if (data->chan) {
			dma_release_channel(data->chan);
			data->chan = NULL;
		}
	}
}

static int sprd_pcm_request_dma_channel(struct snd_pcm_substream *substream,
					int channels)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sprd_pcm_dma_private *dma_private = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	struct device *dev = component->dev;
	struct sprd_pcm_dma_params *dma_params = dma_private->params;
	int i;

	if (channels > SPRD_PCM_CHANNEL_MAX) {
		dev_err(dev, "invalid dma channel number:%d\n", channels);
		return -EINVAL;
	}

	for (i = 0; i < channels; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		data->chan = dma_request_slave_channel(dev,
						       dma_params->chan_name[i]);
		if (!data->chan) {
			dev_err(dev, "failed to request dma channel:%s\n",
				dma_params->chan_name[i]);
			sprd_pcm_release_dma_channel(substream);
			return -ENODEV;
		}
	}

	return 0;
}

static int sprd_pcm_hw_params(struct snd_pcm_substream *substream,
			      struct snd_pcm_hw_params *params)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct sprd_pcm_dma_private *dma_private = runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	struct sprd_pcm_dma_params *dma_params;
	size_t totsize = params_buffer_bytes(params);
	size_t period = params_period_bytes(params);
	int channels = params_channels(params);
	int is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
	struct scatterlist *sg;
	unsigned long flags;
	int ret, i, j, sg_num;

	dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
	if (!dma_params) {
		dev_warn(component->dev, "no dma parameters setting\n");
		dma_private->params = NULL;
		snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
		runtime->dma_bytes = totsize;
		return 0;
	}

	if (!dma_private->params) {
		dma_private->params = dma_params;
		ret = sprd_pcm_request_dma_channel(substream, channels);
		if (ret)
			return ret;
	}

	snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);

	runtime->dma_bytes = totsize;
	sg_num = totsize / period;
	dma_private->dma_addr_offset = totsize / channels;

	sg = devm_kcalloc(component->dev, sg_num, sizeof(*sg), GFP_KERNEL);
	if (!sg) {
		ret = -ENOMEM;
		goto sg_err;
	}

	for (i = 0; i < channels; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];
		struct dma_chan *chan = data->chan;
		struct dma_slave_config config = { };
		struct sprd_dma_linklist link = { };
		enum dma_transfer_direction dir;
		struct scatterlist *sgt = sg;

		config.src_maxburst = dma_params->fragment_len[i];
		config.src_addr_width = dma_params->datawidth[i];
		config.dst_addr_width = dma_params->datawidth[i];
		if (is_playback) {
			config.src_addr = runtime->dma_addr +
				i * dma_private->dma_addr_offset;
			config.dst_addr = dma_params->dev_phys[i];
			dir = DMA_MEM_TO_DEV;
		} else {
			config.src_addr = dma_params->dev_phys[i];
			config.dst_addr = runtime->dma_addr +
				i * dma_private->dma_addr_offset;
			dir = DMA_DEV_TO_MEM;
		}

		sg_init_table(sgt, sg_num);
		for (j = 0; j < sg_num; j++, sgt++) {
			u32 sg_len = period / channels;

			sg_dma_len(sgt) = sg_len;
			sg_dma_address(sgt) = runtime->dma_addr +
				i * dma_private->dma_addr_offset + sg_len * j;
		}

		/*
		 * Configure the link-list address for the DMA engine link-list
		 * mode.
		 */
		link.virt_addr = (unsigned long)data->virt;
		link.phy_addr = data->phys;

		ret = dmaengine_slave_config(chan, &config);
		if (ret) {
			dev_err(component->dev,
				"failed to set slave configuration: %d\n", ret);
			goto config_err;
		}

		/*
		 * We configure the DMA request mode, interrupt mode, channel
		 * mode and channel trigger mode by the flags.
		 */
		flags = SPRD_DMA_FLAGS(SPRD_DMA_CHN_MODE_NONE, SPRD_DMA_NO_TRG,
				       SPRD_DMA_FRAG_REQ, SPRD_DMA_TRANS_INT);
		data->desc = chan->device->device_prep_slave_sg(chan, sg,
								sg_num, dir,
								flags, &link);
		if (!data->desc) {
			dev_err(component->dev, "failed to prepare slave sg\n");
			ret = -ENOMEM;
			goto config_err;
		}

		if (!runtime->no_period_wakeup) {
			data->desc->callback = sprd_pcm_dma_complete;
			data->desc->callback_param = dma_private;
		}
	}

	devm_kfree(component->dev, sg);

	return 0;

config_err:
	devm_kfree(component->dev, sg);
sg_err:
	sprd_pcm_release_dma_channel(substream);
	return ret;
}

static int sprd_pcm_hw_free(struct snd_pcm_substream *substream)
{
	snd_pcm_set_runtime_buffer(substream, NULL);
	sprd_pcm_release_dma_channel(substream);

	return 0;
}

static int sprd_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct sprd_pcm_dma_private *dma_private =
		substream->runtime->private_data;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	int ret = 0, i;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		for (i = 0; i < dma_private->hw_chan; i++) {
			struct sprd_pcm_dma_data *data = &dma_private->data[i];

			if (!data->desc)
				continue;

			data->cookie = dmaengine_submit(data->desc);
			ret = dma_submit_error(data->cookie);
			if (ret) {
				dev_err(component->dev,
					"failed to submit dma request: %d\n",
					ret);
				return ret;
			}

			dma_async_issue_pending(data->chan);
		}

		break;
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		for (i = 0; i < dma_private->hw_chan; i++) {
			struct sprd_pcm_dma_data *data = &dma_private->data[i];

			if (data->chan)
				dmaengine_resume(data->chan);
		}

		break;
	case SNDRV_PCM_TRIGGER_STOP:
		for (i = 0; i < dma_private->hw_chan; i++) {
			struct sprd_pcm_dma_data *data = &dma_private->data[i];

			if (data->chan)
				dmaengine_terminate_async(data->chan);
		}

		break;
	case SNDRV_PCM_TRIGGER_SUSPEND:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		for (i = 0; i < dma_private->hw_chan; i++) {
			struct sprd_pcm_dma_data *data = &dma_private->data[i];

			if (data->chan)
				dmaengine_pause(data->chan);
		}

		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static snd_pcm_uframes_t sprd_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct sprd_pcm_dma_private *dma_private = runtime->private_data;
	struct snd_soc_component *component =
		snd_soc_rtdcom_lookup(rtd, DRV_NAME);
	int pointer[SPRD_PCM_CHANNEL_MAX];
	int bytes_of_pointer = 0, sel_max = 0, i;
	snd_pcm_uframes_t x;
	struct dma_tx_state state;
	enum dma_status status;

	for (i = 0; i < dma_private->hw_chan; i++) {
		struct sprd_pcm_dma_data *data = &dma_private->data[i];

		if (!data->chan)
			continue;

		status = dmaengine_tx_status(data->chan, data->cookie, &state);
		if (status == DMA_ERROR) {
			dev_err(component->dev,
				"failed to get dma channel %d status\n", i);
			return 0;
		}

		/*
		 * We just get current transfer address from the DMA engine, so
		 * we need convert to current pointer.
		 */
		pointer[i] = state.residue - runtime->dma_addr -
			i * dma_private->dma_addr_offset;

		if (i == 0) {
			bytes_of_pointer = pointer[i];
			sel_max = pointer[i] < data->pre_pointer ? 1 : 0;
		} else {
			sel_max ^= pointer[i] < data->pre_pointer ? 1 : 0;

			if (sel_max)
				bytes_of_pointer =
					max(pointer[i], pointer[i - 1]) << 1;
			else
				bytes_of_pointer =
					min(pointer[i], pointer[i - 1]) << 1;
		}

		data->pre_pointer = pointer[i];
	}

	x = bytes_to_frames(runtime, bytes_of_pointer);
	if (x == runtime->buffer_size)
		x = 0;

	return x;
}

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

	vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
	return remap_pfn_range(vma, vma->vm_start,
			       runtime->dma_addr >> PAGE_SHIFT,
			       vma->vm_end - vma->vm_start,
			       vma->vm_page_prot);
}

static struct snd_pcm_ops sprd_pcm_ops = {
	.open = sprd_pcm_open,
	.close = sprd_pcm_close,
	.ioctl = snd_pcm_lib_ioctl,
	.hw_params = sprd_pcm_hw_params,
	.hw_free = sprd_pcm_hw_free,
	.trigger = sprd_pcm_trigger,
	.pointer = sprd_pcm_pointer,
	.mmap = sprd_pcm_mmap,
};

static int sprd_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_card *card = rtd->card->snd_card;
	struct snd_pcm *pcm = rtd->pcm;
	struct snd_pcm_substream *substream;
	int ret;

	ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
	if (ret)
		return ret;

	substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
	if (substream) {
		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
					  sprd_pcm_hardware.buffer_bytes_max,
					  &substream->dma_buffer);
		if (ret) {
			dev_err(card->dev,
				"can't alloc playback dma buffer: %d\n", ret);
			return ret;
		}
	}

	substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
	if (substream) {
		ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, card->dev,
					  sprd_pcm_hardware.buffer_bytes_max,
					  &substream->dma_buffer);
		if (ret) {
			dev_err(card->dev,
				"can't alloc capture dma buffer: %d\n", ret);
			snd_dma_free_pages(&pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->dma_buffer);
			return ret;
		}
	}

	return 0;
}

static void sprd_pcm_free(struct snd_pcm *pcm)
{
	struct snd_pcm_substream *substream;
	int i;

	for (i = 0; i < ARRAY_SIZE(pcm->streams); i++) {
		substream = pcm->streams[i].substream;
		if (substream) {
			snd_dma_free_pages(&substream->dma_buffer);
			substream->dma_buffer.area = NULL;
			substream->dma_buffer.addr = 0;
		}
	}
}

static const struct snd_soc_component_driver sprd_soc_component = {
	.name		= DRV_NAME,
	.ops		= &sprd_pcm_ops,
	.pcm_new	= sprd_pcm_new,
	.pcm_free	= sprd_pcm_free,
};

static int sprd_soc_platform_probe(struct platform_device *pdev)
{
	int ret;

	ret = devm_snd_soc_register_component(&pdev->dev, &sprd_soc_component,
					      NULL, 0);
	if (ret)
		dev_err(&pdev->dev, "could not register platform:%d\n", ret);

	return ret;
}

static const struct of_device_id sprd_pcm_of_match[] = {
	{ .compatible = "sprd,pcm-platform", },
	{ },
};
MODULE_DEVICE_TABLE(of, sprd_pcm_of_match);

static struct platform_driver sprd_pcm_driver = {
	.driver = {
		.name = "sprd-pcm-audio",
		.of_match_table = sprd_pcm_of_match,
	},

	.probe = sprd_soc_platform_probe,
};

module_platform_driver(sprd_pcm_driver);

MODULE_DESCRIPTION("Spreadtrum ASoC PCM DMA");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:sprd-audio");
