// SPDX-License-Identifier: GPL-2.0-only
/*
 *  sst_mfld_platform.c - Intel MID Platform driver
 *
 *  Copyright (C) 2010-2014 Intel Corp
 *  Author: Vinod Koul <vinod.koul@intel.com>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/slab.h>
#include <linux/io.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/compress_driver.h>
#include "sst-mfld-platform.h"

/* compress stream operations */
static void sst_compr_fragment_elapsed(void *arg)
{
	struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;

	pr_debug("fragment elapsed by driver\n");
	if (cstream)
		snd_compr_fragment_elapsed(cstream);
}

static void sst_drain_notify(void *arg)
{
	struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg;

	pr_debug("drain notify by driver\n");
	if (cstream)
		snd_compr_drain_notify(cstream);
}

static int sst_platform_compr_open(struct snd_soc_component *component,
				   struct snd_compr_stream *cstream)
{

	int ret_val = 0;
	struct snd_compr_runtime *runtime = cstream->runtime;
	struct sst_runtime_stream *stream;

	stream = kzalloc(sizeof(*stream), GFP_KERNEL);
	if (!stream)
		return -ENOMEM;

	spin_lock_init(&stream->status_lock);

	/* get the sst ops */
	if (!sst || !try_module_get(sst->dev->driver->owner)) {
		pr_err("no device available to run\n");
		ret_val = -ENODEV;
		goto out_ops;
	}
	stream->compr_ops = sst->compr_ops;
	stream->id = 0;

	/* Turn on LPE */
	sst->compr_ops->power(sst->dev, true);

	sst_set_stream_status(stream, SST_PLATFORM_INIT);
	runtime->private_data = stream;
	return 0;
out_ops:
	kfree(stream);
	return ret_val;
}

static int sst_platform_compr_free(struct snd_soc_component *component,
				   struct snd_compr_stream *cstream)
{
	struct sst_runtime_stream *stream;
	int ret_val = 0, str_id;

	stream = cstream->runtime->private_data;
	/* Turn off LPE */
	sst->compr_ops->power(sst->dev, false);

	/*need to check*/
	str_id = stream->id;
	if (str_id)
		ret_val = stream->compr_ops->close(sst->dev, str_id);
	module_put(sst->dev->driver->owner);
	kfree(stream);
	pr_debug("%s: %d\n", __func__, ret_val);
	return 0;
}

static int sst_platform_compr_set_params(struct snd_soc_component *component,
					 struct snd_compr_stream *cstream,
					 struct snd_compr_params *params)
{
	struct sst_runtime_stream *stream;
	int retval;
	struct snd_sst_params str_params;
	struct sst_compress_cb cb;
	struct sst_data *ctx = snd_soc_component_get_drvdata(component);

	stream = cstream->runtime->private_data;
	/* construct fw structure for this*/
	memset(&str_params, 0, sizeof(str_params));

	/* fill the device type and stream id to pass to SST driver */
	retval = sst_fill_stream_params(cstream, ctx, &str_params, true);
	pr_debug("compr_set_params: fill stream params ret_val = 0x%x\n", retval);
	if (retval < 0)
		return retval;

	switch (params->codec.id) {
	case SND_AUDIOCODEC_MP3: {
		str_params.codec = SST_CODEC_TYPE_MP3;
		str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in;
		str_params.sparams.uc.mp3_params.pcm_wd_sz = 16;
		break;
	}

	case SND_AUDIOCODEC_AAC: {
		str_params.codec = SST_CODEC_TYPE_AAC;
		str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in;
		str_params.sparams.uc.aac_params.pcm_wd_sz = 16;
		if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS)
			str_params.sparams.uc.aac_params.bs_format =
							AAC_BIT_STREAM_ADTS;
		else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW)
			str_params.sparams.uc.aac_params.bs_format =
							AAC_BIT_STREAM_RAW;
		else {
			pr_err("Undefined format%d\n", params->codec.format);
			return -EINVAL;
		}
		str_params.sparams.uc.aac_params.externalsr =
						params->codec.sample_rate;
		break;
	}

	default:
		pr_err("codec not supported, id =%d\n", params->codec.id);
		return -EINVAL;
	}

	str_params.aparams.ring_buf_info[0].addr  =
					virt_to_phys(cstream->runtime->buffer);
	str_params.aparams.ring_buf_info[0].size =
					cstream->runtime->buffer_size;
	str_params.aparams.sg_count = 1;
	str_params.aparams.frag_size = cstream->runtime->fragment_size;

	cb.param = cstream;
	cb.compr_cb = sst_compr_fragment_elapsed;
	cb.drain_cb_param = cstream;
	cb.drain_notify = sst_drain_notify;

	retval = stream->compr_ops->open(sst->dev, &str_params, &cb);
	if (retval < 0) {
		pr_err("stream allocation failed %d\n", retval);
		return retval;
	}

	stream->id = retval;
	return 0;
}

static int sst_platform_compr_trigger(struct snd_soc_component *component,
				      struct snd_compr_stream *cstream, int cmd)
{
	struct sst_runtime_stream *stream = cstream->runtime->private_data;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		if (stream->compr_ops->stream_start)
			return stream->compr_ops->stream_start(sst->dev, stream->id);
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		if (stream->compr_ops->stream_drop)
			return stream->compr_ops->stream_drop(sst->dev, stream->id);
		break;
	case SND_COMPR_TRIGGER_DRAIN:
		if (stream->compr_ops->stream_drain)
			return stream->compr_ops->stream_drain(sst->dev, stream->id);
		break;
	case SND_COMPR_TRIGGER_PARTIAL_DRAIN:
		if (stream->compr_ops->stream_partial_drain)
			return stream->compr_ops->stream_partial_drain(sst->dev, stream->id);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		if (stream->compr_ops->stream_pause)
			return stream->compr_ops->stream_pause(sst->dev, stream->id);
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		if (stream->compr_ops->stream_pause_release)
			return stream->compr_ops->stream_pause_release(sst->dev, stream->id);
		break;
	}
	return -EINVAL;
}

static int sst_platform_compr_pointer(struct snd_soc_component *component,
				      struct snd_compr_stream *cstream,
				      struct snd_compr_tstamp *tstamp)
{
	struct sst_runtime_stream *stream;

	stream  = cstream->runtime->private_data;
	stream->compr_ops->tstamp(sst->dev, stream->id, tstamp);
	tstamp->byte_offset = tstamp->copied_total %
				 (u32)cstream->runtime->buffer_size;
	pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset);
	return 0;
}

static int sst_platform_compr_ack(struct snd_soc_component *component,
				  struct snd_compr_stream *cstream,
				  size_t bytes)
{
	struct sst_runtime_stream *stream;

	stream  = cstream->runtime->private_data;
	stream->compr_ops->ack(sst->dev, stream->id, (unsigned long)bytes);
	stream->bytes_written += bytes;

	return 0;
}

static int sst_platform_compr_get_caps(struct snd_soc_component *component,
				       struct snd_compr_stream *cstream,
				       struct snd_compr_caps *caps)
{
	struct sst_runtime_stream *stream =
		cstream->runtime->private_data;

	return stream->compr_ops->get_caps(caps);
}

static int sst_platform_compr_get_codec_caps(struct snd_soc_component *component,
					     struct snd_compr_stream *cstream,
					     struct snd_compr_codec_caps *codec)
{
	struct sst_runtime_stream *stream =
		cstream->runtime->private_data;

	return stream->compr_ops->get_codec_caps(codec);
}

static int sst_platform_compr_set_metadata(struct snd_soc_component *component,
					   struct snd_compr_stream *cstream,
					   struct snd_compr_metadata *metadata)
{
	struct sst_runtime_stream *stream  =
		 cstream->runtime->private_data;

	return stream->compr_ops->set_metadata(sst->dev, stream->id, metadata);
}

const struct snd_compress_ops sst_platform_compress_ops = {

	.open = sst_platform_compr_open,
	.free = sst_platform_compr_free,
	.set_params = sst_platform_compr_set_params,
	.set_metadata = sst_platform_compr_set_metadata,
	.trigger = sst_platform_compr_trigger,
	.pointer = sst_platform_compr_pointer,
	.ack = sst_platform_compr_ack,
	.get_caps = sst_platform_compr_get_caps,
	.get_codec_caps = sst_platform_compr_get_codec_caps,
};
