/*
 *  intel_sst_interface.c - Intel SST Driver for audio engine
 *
 *  Copyright (C) 2008-10 Intel Corp
 *  Authors:	Vinod Koul <vinod.koul@intel.com>
 *		Harsha Priya <priya.harsha@intel.com>
 *		Dharageswari R <dharageswari.r@intel.com)
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  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; version 2 of the License.
 *
 *  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.,
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *  This driver exposes the audio engine functionalities to the ALSA
 *	and middleware.
 *  Upper layer interfaces (MAD driver, MMF) to SST driver
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/delay.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include "intel_sst.h"
#include "intel_sst_ioctl.h"
#include "intel_sst_fw_ipc.h"
#include "intel_sst_common.h"


/*
 * sst_download_fw - download the audio firmware to DSP
 *
 * This function is called when the FW needs to be downloaded to SST DSP engine
 */
int sst_download_fw(void)
{
	int retval;
	const struct firmware *fw_sst;
	char name[20];

	if (sst_drv_ctx->sst_state != SST_UN_INIT)
		return -EPERM;

	snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_",
					sst_drv_ctx->pci_id, ".bin");

	pr_debug("Downloading %s FW now...\n", name);
	retval = request_firmware(&fw_sst, name, &sst_drv_ctx->pci->dev);
	if (retval) {
		pr_err("request fw failed %d\n", retval);
		return retval;
	}
	sst_drv_ctx->alloc_block[0].sst_id = FW_DWNL_ID;
	sst_drv_ctx->alloc_block[0].ops_block.condition = false;
	retval = sst_load_fw(fw_sst, NULL);
	if (retval)
		goto end_restore;

	retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[0]);
	if (retval)
		pr_err("fw download failed %d\n" , retval);
end_restore:
	release_firmware(fw_sst);
	sst_drv_ctx->alloc_block[0].sst_id = BLOCK_UNINIT;
	return retval;
}


/*
 * sst_stalled - this function checks if the lpe is in stalled state
 */
int sst_stalled(void)
{
	int retry = 1000;
	int retval = -1;

	while (retry) {
		if (!sst_drv_ctx->lpe_stalled)
			return 0;
		/*wait for time and re-check*/
		msleep(1);

		retry--;
	}
	pr_debug("in Stalled State\n");
	return retval;
}

void free_stream_context(unsigned int str_id)
{
	struct stream_info *stream;

	if (!sst_validate_strid(str_id)) {
		/* str_id is valid, so stream is alloacted */
		stream = &sst_drv_ctx->streams[str_id];
		if (sst_free_stream(str_id))
			sst_clean_stream(&sst_drv_ctx->streams[str_id]);
		if (stream->ops == STREAM_OPS_PLAYBACK ||
				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
			sst_drv_ctx->pb_streams--;
			if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID)
				sst_drv_ctx->scard_ops->power_down_pmic_pb(
						stream->device);
			else {
				if (sst_drv_ctx->pb_streams == 0)
					sst_drv_ctx->scard_ops->
					power_down_pmic_pb(stream->device);
			}
		} else if (stream->ops == STREAM_OPS_CAPTURE) {
			sst_drv_ctx->cp_streams--;
			if (sst_drv_ctx->cp_streams == 0)
				sst_drv_ctx->scard_ops->power_down_pmic_cp(
						stream->device);
		}
		if (sst_drv_ctx->pb_streams == 0
				&& sst_drv_ctx->cp_streams == 0)
			sst_drv_ctx->scard_ops->power_down_pmic();
	}
}

/*
 * sst_get_stream_allocated - this function gets a stream allocated with
 * the given params
 *
 * @str_param : stream params
 * @lib_dnld : pointer to pointer of lib downlaod struct
 *
 * This creates new stream id for a stream, in case lib is to be downloaded to
 * DSP, it downloads that
 */
int sst_get_stream_allocated(struct snd_sst_params *str_param,
		struct snd_sst_lib_download **lib_dnld)
{
	int retval, str_id;
	struct stream_info *str_info;

	retval = sst_alloc_stream((char *) &str_param->sparams, str_param->ops,
				str_param->codec, str_param->device_type);
	if (retval < 0) {
		pr_err("sst_alloc_stream failed %d\n", retval);
		return retval;
	}
	pr_debug("Stream allocated %d\n", retval);
	str_id = retval;
	str_info = &sst_drv_ctx->streams[str_id];
	/* Block the call for reply */
	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
			&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
	if ((retval != 0) || (str_info->ctrl_blk.ret_code != 0)) {
		pr_debug("FW alloc failed retval %d, ret_code %d\n",
				retval, str_info->ctrl_blk.ret_code);
		str_id = -str_info->ctrl_blk.ret_code; /*return error*/
		*lib_dnld = str_info->ctrl_blk.data;
		sst_clean_stream(str_info);
	} else
		pr_debug("FW Stream allocated success\n");
	return str_id; /*will ret either error (in above if) or correct str id*/
}

/*
 * sst_get_sfreq - this function returns the frequency of the stream
 *
 * @str_param : stream params
 */
static int sst_get_sfreq(struct snd_sst_params *str_param)
{
	switch (str_param->codec) {
	case SST_CODEC_TYPE_PCM:
		return 48000; /*str_param->sparams.uc.pcm_params.sfreq;*/
	case SST_CODEC_TYPE_MP3:
		return str_param->sparams.uc.mp3_params.sfreq;
	case SST_CODEC_TYPE_AAC:
		return str_param->sparams.uc.aac_params.sfreq;
	case SST_CODEC_TYPE_WMA9:
		return str_param->sparams.uc.wma_params.sfreq;
	default:
		return 0;
	}
}

/*
 * sst_get_stream - this function prepares for stream allocation
 *
 * @str_param : stream param
 */
int sst_get_stream(struct snd_sst_params *str_param)
{
	int i, retval;
	struct stream_info *str_info;
	struct snd_sst_lib_download *lib_dnld;

	/* stream is not allocated, we are allocating */
	retval = sst_get_stream_allocated(str_param, &lib_dnld);
	if (retval == -(SST_LIB_ERR_LIB_DNLD_REQUIRED)) {
		/* codec download is required */
		struct snd_sst_alloc_response *response;

		pr_debug("Codec is required.... trying that\n");
		if (lib_dnld == NULL) {
			pr_err("lib download null!!! abort\n");
			return -EIO;
		}
		i = sst_get_block_stream(sst_drv_ctx);
		response = sst_drv_ctx->alloc_block[i].ops_block.data;
		pr_debug("alloc block allocated = %d\n", i);
		if (i < 0) {
			kfree(lib_dnld);
			return -ENOMEM;
		}
		retval = sst_load_library(lib_dnld, str_param->ops);
		kfree(lib_dnld);

		sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
		if (!retval) {
			pr_debug("codec was downloaded successfully\n");

			retval = sst_get_stream_allocated(str_param, &lib_dnld);
			if (retval <= 0)
				goto err;

			pr_debug("Alloc done stream id %d\n", retval);
		} else {
			pr_debug("codec download failed\n");
			retval = -EIO;
			goto err;
		}
	} else if  (retval <= 0)
		goto err;
	/*else
		set_port_params(str_param, str_param->ops);*/

	/* store sampling freq */
	str_info = &sst_drv_ctx->streams[retval];
	str_info->sfreq = sst_get_sfreq(str_param);

	/* power on the analog, if reqd */
	if (str_param->ops == STREAM_OPS_PLAYBACK ||
			str_param->ops == STREAM_OPS_PLAYBACK_DRM) {
		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
			sst_drv_ctx->scard_ops->power_up_pmic_pb(
					sst_drv_ctx->pmic_port_instance);
		else
			sst_drv_ctx->scard_ops->power_up_pmic_pb(
							str_info->device);
		/*Only if the playback is MP3 - Send a message*/
		sst_drv_ctx->pb_streams++;
	} else if (str_param->ops == STREAM_OPS_CAPTURE) {

		sst_drv_ctx->scard_ops->power_up_pmic_cp(
				sst_drv_ctx->pmic_port_instance);
		/*Send a messageif not sent already*/
		sst_drv_ctx->cp_streams++;
	}

err:
	return retval;
}

void sst_process_mad_ops(struct work_struct *work)
{

	struct mad_ops_wq *mad_ops =
			container_of(work, struct mad_ops_wq, wq);
	int retval = 0;

	switch (mad_ops->control_op) {
	case SST_SND_PAUSE:
		retval = sst_pause_stream(mad_ops->stream_id);
		break;
	case SST_SND_RESUME:
		retval = sst_resume_stream(mad_ops->stream_id);
		break;
	case SST_SND_DROP:
		retval = sst_drop_stream(mad_ops->stream_id);
		break;
	case SST_SND_START:
			pr_debug("SST Debug: start stream\n");
		retval = sst_start_stream(mad_ops->stream_id);
		break;
	case SST_SND_STREAM_PROCESS:
		pr_debug("play/capt frames...\n");
		break;
	default:
		pr_err(" wrong control_ops reported\n");
	}
	return;
}

void send_intial_rx_timeslot(void)
{
	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID &&
			sst_drv_ctx->rx_time_slot_status != RX_TIMESLOT_UNINIT
			&& sst_drv_ctx->pmic_vendor != SND_NC)
		sst_enable_rx_timeslot(sst_drv_ctx->rx_time_slot_status);
}

/*
 * sst_open_pcm_stream - Open PCM interface
 *
 * @str_param: parameters of pcm stream
 *
 * This function is called by MID sound card driver to open
 * a new pcm interface
 */
int sst_open_pcm_stream(struct snd_sst_params *str_param)
{
	struct stream_info *str_info;
	int retval;

	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);

	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
		/* LPE is suspended, resume it before proceeding*/
		pr_debug("Resuming from Suspended state\n");
		retval = intel_sst_resume(sst_drv_ctx->pci);
		if (retval) {
			pr_err("Resume Failed = %#x, abort\n", retval);
			pm_runtime_put(&sst_drv_ctx->pci->dev);
			return retval;
		}
	}
	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
		/* FW is not downloaded */
		pr_debug("DSP Downloading FW now...\n");
		retval = sst_download_fw();
		if (retval) {
			pr_err("FW download fail %x, abort\n", retval);
			pm_runtime_put(&sst_drv_ctx->pci->dev);
			return retval;
		}
		send_intial_rx_timeslot();
	}

	if (!str_param) {
		pm_runtime_put(&sst_drv_ctx->pci->dev);
		return -EINVAL;
	}

	retval = sst_get_stream(str_param);
	if (retval > 0) {
		sst_drv_ctx->stream_cnt++;
		str_info = &sst_drv_ctx->streams[retval];
		str_info->src = MAD_DRV;
	} else
		pm_runtime_put(&sst_drv_ctx->pci->dev);

	return retval;
}

/*
 * sst_close_pcm_stream - Close PCM interface
 *
 * @str_id: stream id to be closed
 *
 * This function is called by MID sound card driver to close
 * an existing pcm interface
 */
int sst_close_pcm_stream(unsigned int str_id)
{
	struct stream_info *stream;

	pr_debug("sst: stream free called\n");
	if (sst_validate_strid(str_id))
		return -EINVAL;
	stream = &sst_drv_ctx->streams[str_id];
	free_stream_context(str_id);
	stream->pcm_substream = NULL;
	stream->status = STREAM_UN_INIT;
	stream->period_elapsed = NULL;
	sst_drv_ctx->stream_cnt--;
	pr_debug("sst: will call runtime put now\n");
	pm_runtime_put(&sst_drv_ctx->pci->dev);
	return 0;
}

/*
 * sst_device_control - Set Control params
 *
 * @cmd: control cmd to be set
 * @arg: command argument
 *
 * This function is called by MID sound card driver to set
 * SST/Sound card controls for an opened stream.
 * This is registered with MID driver
 */
int sst_device_control(int cmd, void *arg)
{
	int retval = 0, str_id = 0;

	switch (cmd) {
	case SST_SND_PAUSE:
	case SST_SND_RESUME:
	case SST_SND_DROP:
	case SST_SND_START:
		sst_drv_ctx->mad_ops.control_op = cmd;
		sst_drv_ctx->mad_ops.stream_id = *(int *)arg;
		queue_work(sst_drv_ctx->mad_wq, &sst_drv_ctx->mad_ops.wq);
		break;

	case SST_SND_STREAM_INIT: {
		struct pcm_stream_info *str_info;
		struct stream_info *stream;

		pr_debug("stream init called\n");
		str_info = (struct pcm_stream_info *)arg;
		str_id = str_info->str_id;
		retval = sst_validate_strid(str_id);
		if (retval)
			break;

		stream = &sst_drv_ctx->streams[str_id];
		pr_debug("setting the period ptrs\n");
		stream->pcm_substream = str_info->mad_substream;
		stream->period_elapsed = str_info->period_elapsed;
		stream->sfreq = str_info->sfreq;
		stream->prev = stream->status;
		stream->status = STREAM_INIT;
		break;
	}

	case SST_SND_BUFFER_POINTER: {
		struct pcm_stream_info *stream_info;
		struct snd_sst_tstamp fw_tstamp = {0,};
		struct stream_info *stream;


		stream_info = (struct pcm_stream_info *)arg;
		str_id = stream_info->str_id;
		retval = sst_validate_strid(str_id);
		if (retval)
			break;
		stream = &sst_drv_ctx->streams[str_id];

		if (!stream->pcm_substream)
			break;
		memcpy_fromio(&fw_tstamp,
			((void *)(sst_drv_ctx->mailbox + SST_TIME_STAMP)
			+(str_id * sizeof(fw_tstamp))),
			sizeof(fw_tstamp));

		pr_debug("Pointer Query on strid = %d ops %d\n",
						str_id, stream->ops);

		if (stream->ops == STREAM_OPS_PLAYBACK)
			stream_info->buffer_ptr = fw_tstamp.samples_rendered;
		else
			stream_info->buffer_ptr = fw_tstamp.samples_processed;
		pr_debug("Samples rendered = %llu, buffer ptr %llu\n",
			fw_tstamp.samples_rendered, stream_info->buffer_ptr);
		break;
	}
	case SST_ENABLE_RX_TIME_SLOT: {
		int status = *(int *)arg;
		sst_drv_ctx->rx_time_slot_status = status ;
		sst_enable_rx_timeslot(status);
		break;
	}
	default:
		/* Illegal case */
		pr_warn("illegal req\n");
		return -EINVAL;
	}

	return retval;
}


struct intel_sst_pcm_control pcm_ops = {
	.open = sst_open_pcm_stream,
	.device_control = sst_device_control,
	.close = sst_close_pcm_stream,
};

struct intel_sst_card_ops sst_pmic_ops = {
	.pcm_control = &pcm_ops,
};

/*
 * register_sst_card - function for sound card to register
 *
 * @card: pointer to structure of operations
 *
 * This function is called card driver loads and is ready for registration
 */
int register_sst_card(struct intel_sst_card_ops *card)
{
	if (!sst_drv_ctx) {
		pr_err("No SST driver register card reject\n");
		return -ENODEV;
	}

	if (!card || !card->module_name) {
		pr_err("Null Pointer Passed\n");
		return -EINVAL;
	}
	if (sst_drv_ctx->pmic_state == SND_MAD_UN_INIT) {
		/* register this driver */
		if ((strncmp(SST_CARD_NAMES, card->module_name,
				strlen(SST_CARD_NAMES))) == 0) {
			sst_drv_ctx->pmic_vendor = card->vendor_id;
			sst_drv_ctx->scard_ops =  card->scard_ops;
			sst_pmic_ops.module_name = card->module_name;
			sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
			sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
			card->pcm_control = sst_pmic_ops.pcm_control;
			return 0;
		} else {
			pr_err("strcmp fail %s\n", card->module_name);
			return -EINVAL;
		}

	} else {
		/* already registered a driver */
		pr_err("Repeat for registration..denied\n");
		return -EBADRQC;
	}
	/* The ASoC code doesn't set scard_ops */
	if (sst_drv_ctx->scard_ops)
		sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
	return 0;
}
EXPORT_SYMBOL_GPL(register_sst_card);

/*
 * unregister_sst_card- function for sound card to un-register
 *
 * @card: pointer to structure of operations
 *
 * This function is called when card driver unloads
 */
void unregister_sst_card(struct intel_sst_card_ops *card)
{
	if (sst_pmic_ops.pcm_control == card->pcm_control) {
		/* unreg */
		sst_pmic_ops.module_name = "";
		sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
		pr_debug("Unregistered %s\n", card->module_name);
	}
	return;
}
EXPORT_SYMBOL_GPL(unregister_sst_card);
