/*
 *  intel_sst_stream.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>
 *		KP Jeeja <jeeja.kp@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 file contains the stream operations of SST driver
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/pci.h>
#include <linux/syscalls.h>
#include <linux/firmware.h>
#include <linux/sched.h>
#ifdef CONFIG_MRST_RAR_HANDLER
#include <linux/rar_register.h>
#include "../memrar/memrar.h"
#endif
#include "intel_sst_ioctl.h"
#include "intel_sst.h"
#include "intel_sst_fw_ipc.h"
#include "intel_sst_common.h"
/**
* sst_get_stream_params - Send msg to query for stream parameters
* @str_id:	stream id for which the parameters are queried for
* @get_params:	out parameters to which the parameters are copied to
*
* This function is called when the stream parameters are queiried for
*/
int sst_get_stream_params(int str_id,
			struct snd_sst_get_stream_params *get_params)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct stream_info *str_info;
	struct snd_sst_fw_get_stream_params *fw_params;

	pr_debug("get_stream for %d\n", str_id);
	retval = sst_validate_strid(str_id);
	if (retval)
		return retval;

	str_info = &sst_drv_ctx->streams[str_id];
	if (str_info->status != STREAM_UN_INIT) {
		if (str_info->ctrl_blk.on == true) {
			pr_err("control path in use\n");
			return -EINVAL;
		}
		if (sst_create_short_msg(&msg)) {
			pr_err("message creation failed\n");
			return -ENOMEM;
		}
		fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC);
		if (!fw_params) {
			pr_err("mem allocation failed\n");
			kfree(msg);
			return -ENOMEM;
		}

		sst_fill_header(&msg->header, IPC_IA_GET_STREAM_PARAMS,
					0, str_id);
		str_info->ctrl_blk.condition = false;
		str_info->ctrl_blk.ret_code = 0;
		str_info->ctrl_blk.on = true;
		str_info->ctrl_blk.data = (void *) fw_params;
		spin_lock(&sst_drv_ctx->list_spin_lock);
		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
		spin_unlock(&sst_drv_ctx->list_spin_lock);
		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
		if (retval) {
			get_params->codec_params.result = retval;
			kfree(fw_params);
			return -EIO;
		}
		memcpy(&get_params->pcm_params, &fw_params->pcm_params,
				sizeof(fw_params->pcm_params));
		memcpy(&get_params->codec_params.sparams,
				&fw_params->codec_params,
				sizeof(fw_params->codec_params));
		get_params->codec_params.result = 0;
		get_params->codec_params.stream_id = str_id;
		get_params->codec_params.codec = str_info->codec;
		get_params->codec_params.ops = str_info->ops;
		get_params->codec_params.stream_type = str_info->str_type;
		kfree(fw_params);
	} else {
		pr_debug("Stream is not in the init state\n");
	}
	return retval;
}

/**
 * sst_set_stream_param - Send msg for setting stream parameters
 *
 * @str_id: stream id
 * @str_param: stream params
 *
 * This function sets stream params during runtime
 */
int sst_set_stream_param(int str_id, struct snd_sst_params *str_param)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct stream_info *str_info;

	BUG_ON(!str_param);
	if (sst_drv_ctx->streams[str_id].ops != str_param->ops) {
		pr_err("Invalid operation\n");
		return -EINVAL;
	}
	retval = sst_validate_strid(str_id);
	if (retval)
		return retval;
	pr_debug("set_stream for %d\n", str_id);
	str_info =  &sst_drv_ctx->streams[str_id];
	if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) {
		if (str_info->ctrl_blk.on == true) {
			pr_err("control path in use\n");
			return -EAGAIN;
		}
		if (sst_create_large_msg(&msg))
			return -ENOMEM;

		sst_fill_header(&msg->header,
				IPC_IA_SET_STREAM_PARAMS, 1, str_id);
		str_info->ctrl_blk.condition = false;
		str_info->ctrl_blk.ret_code = 0;
		str_info->ctrl_blk.on = true;
		msg->header.part.data = sizeof(u32) +
				sizeof(str_param->sparams);
		memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
		memcpy(msg->mailbox_data + sizeof(u32), &str_param->sparams,
				sizeof(str_param->sparams));
		spin_lock(&sst_drv_ctx->list_spin_lock);
		list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
		spin_unlock(&sst_drv_ctx->list_spin_lock);
		sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
		if (retval < 0) {
			retval = -EIO;
			sst_clean_stream(str_info);
		}
	} else {
		retval = -EBADRQC;
		pr_err("BADQRC for stream\n");
	}
	return retval;
}

/**
* sst_get_vol - This function allows to get the premix gain or gain of a stream
*
* @get_vol: this is an output param through which the volume
*	structure is passed back to user
*
* This function is called when the premix gain or stream gain is queried for
*/
int sst_get_vol(struct snd_sst_vol *get_vol)
{
	int retval = 0;
	struct ipc_post *msg = NULL;
	struct snd_sst_vol *fw_get_vol;
	int str_id = get_vol->stream_id;

	pr_debug("get vol called\n");

	if (sst_create_short_msg(&msg))
		return -ENOMEM;

	sst_fill_header(&msg->header,
				IPC_IA_GET_STREAM_VOL, 0, str_id);
	sst_drv_ctx->vol_info_blk.condition = false;
	sst_drv_ctx->vol_info_blk.ret_code = 0;
	sst_drv_ctx->vol_info_blk.on = true;
	fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC);
	if (!fw_get_vol) {
		pr_err("mem allocation failed\n");
		kfree(msg);
		return -ENOMEM;
	}
	sst_drv_ctx->vol_info_blk.data = (void *)fw_get_vol;
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
			&sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
	if (retval)
		retval = -EIO;
	else {
		pr_debug("stream id %d\n", fw_get_vol->stream_id);
		pr_debug("volume %d\n", fw_get_vol->volume);
		pr_debug("ramp duration %d\n", fw_get_vol->ramp_duration);
		pr_debug("ramp_type %d\n", fw_get_vol->ramp_type);
		memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol));
	}
	return retval;
}

/**
* sst_set_vol - This function allows to set the premix gain or gain of a stream
*
* @set_vol:	this holds the volume structure that needs to be set
*
* This function is called when premix gain or stream gain is requested to be set
*/
int sst_set_vol(struct snd_sst_vol *set_vol)
{

	int retval = 0;
	struct ipc_post *msg = NULL;

	pr_debug("set vol called\n");

	if (sst_create_large_msg(&msg)) {
		pr_err("message creation failed\n");
		return -ENOMEM;
	}
	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1,
				set_vol->stream_id);

	msg->header.part.data = sizeof(u32) + sizeof(*set_vol);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), set_vol, sizeof(*set_vol));
	sst_drv_ctx->vol_info_blk.condition = false;
	sst_drv_ctx->vol_info_blk.ret_code = 0;
	sst_drv_ctx->vol_info_blk.on = true;
	sst_drv_ctx->vol_info_blk.data = set_vol;
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
			&sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT);
	if (retval) {
		pr_err("error in set_vol = %d\n", retval);
		retval = -EIO;
	}
	return retval;
}

/**
* sst_set_mute - This function sets premix mute or soft mute of a stream
*
* @set_mute:	this holds the mute structure that needs to be set
*
* This function is called when premix mute or stream mute requested to be set
*/
int sst_set_mute(struct snd_sst_mute *set_mute)
{

	int retval = 0;
	struct ipc_post *msg = NULL;

	pr_debug("set mute called\n");

	if (sst_create_large_msg(&msg)) {
		pr_err("message creation failed\n");
		return -ENOMEM;
	}
	sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1,
				set_mute->stream_id);
	sst_drv_ctx->mute_info_blk.condition = false;
	sst_drv_ctx->mute_info_blk.ret_code = 0;
	sst_drv_ctx->mute_info_blk.on = true;
	sst_drv_ctx->mute_info_blk.data = set_mute;

	msg->header.part.data = sizeof(u32) + sizeof(*set_mute);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), set_mute,
			sizeof(*set_mute));
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
			&sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT);
	if (retval) {
		pr_err("error in set_mute = %d\n", retval);
		retval = -EIO;
	}
	return retval;
}

int sst_prepare_target(struct snd_sst_slot_info *slot)
{
	if (slot->target_device == SND_SST_TARGET_PMIC
		&& slot->device_instance == 1) {
			/*music mode*/
			if (sst_drv_ctx->pmic_port_instance == 0)
				sst_drv_ctx->scard_ops->set_voice_port(
					DEACTIVATE);
	} else if ((slot->target_device == SND_SST_TARGET_PMIC ||
			slot->target_device == SND_SST_TARGET_MODEM) &&
			slot->device_instance == 0) {
				/*voip mode where pcm0 is active*/
				if (sst_drv_ctx->pmic_port_instance == 1)
					sst_drv_ctx->scard_ops->set_audio_port(
						DEACTIVATE);
	}
	return 0;
}

int sst_activate_target(struct snd_sst_slot_info *slot)
{
	if (slot->target_device == SND_SST_TARGET_PMIC &&
		slot->device_instance == 1) {
			/*music mode*/
			sst_drv_ctx->pmic_port_instance = 1;
			sst_drv_ctx->scard_ops->set_audio_port(ACTIVATE);
			sst_drv_ctx->scard_ops->set_pcm_audio_params(
				slot->pcm_params.sfreq,
				slot->pcm_params.pcm_wd_sz,
				slot->pcm_params.num_chan);
			if (sst_drv_ctx->pb_streams)
				sst_drv_ctx->scard_ops->power_up_pmic_pb(1);
			if (sst_drv_ctx->cp_streams)
				sst_drv_ctx->scard_ops->power_up_pmic_cp(1);
	} else if ((slot->target_device == SND_SST_TARGET_PMIC ||
			slot->target_device == SND_SST_TARGET_MODEM) &&
			slot->device_instance == 0) {
				/*voip mode where pcm0 is active*/
				sst_drv_ctx->pmic_port_instance = 0;
				sst_drv_ctx->scard_ops->set_voice_port(
					ACTIVATE);
				sst_drv_ctx->scard_ops->power_up_pmic_pb(0);
				/*sst_drv_ctx->scard_ops->power_up_pmic_cp(0);*/
	}
	return 0;
}

int sst_parse_target(struct snd_sst_slot_info *slot)
{
	int retval = 0;

	if (slot->action == SND_SST_PORT_ACTIVATE &&
		slot->device_type == SND_SST_DEVICE_PCM) {
			retval = sst_activate_target(slot);
			if (retval)
				pr_err("SST_Activate_target_fail\n");
			else
				pr_err("SST_Activate_target_pass\n");
	} else if (slot->action == SND_SST_PORT_PREPARE &&
			slot->device_type == SND_SST_DEVICE_PCM) {
				retval = sst_prepare_target(slot);
			if (retval)
				pr_err("SST_prepare_target_fail\n");
			else
				pr_err("SST_prepare_target_pass\n");
	} else {
		pr_err("slot_action : %d, device_type: %d\n",
				slot->action, slot->device_type);
	}
	return retval;
}

int sst_send_target(struct snd_sst_target_device *target)
{
	int retval;
	struct ipc_post *msg;

	if (sst_create_large_msg(&msg)) {
		pr_err("message creation failed\n");
		return -ENOMEM;
	}
	sst_fill_header(&msg->header, IPC_IA_TARGET_DEV_SELECT, 1, 0);
	sst_drv_ctx->tgt_dev_blk.condition = false;
	sst_drv_ctx->tgt_dev_blk.ret_code = 0;
	sst_drv_ctx->tgt_dev_blk.on = true;

	msg->header.part.data = sizeof(u32) + sizeof(*target);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), target,
			sizeof(*target));
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	pr_debug("message sent- waiting\n");
	retval = sst_wait_interruptible_timeout(sst_drv_ctx,
			&sst_drv_ctx->tgt_dev_blk, TARGET_DEV_BLOCK_TIMEOUT);
	if (retval)
		pr_err("target device ipc failed = 0x%x\n", retval);
	return retval;

}

int sst_target_device_validate(struct snd_sst_target_device *target)
{
	int retval = 0;
       int i;

	for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
		if (target->devices[i].device_type == SND_SST_DEVICE_PCM) {
			/*pcm device, check params*/
			if (target->devices[i].device_instance == 1) {
				if ((target->devices[i].device_mode !=
				SND_SST_DEV_MODE_PCM_MODE4_I2S) &&
				(target->devices[i].device_mode !=
				SND_SST_DEV_MODE_PCM_MODE4_RIGHT_JUSTIFIED)
				&& (target->devices[i].device_mode !=
				SND_SST_DEV_MODE_PCM_MODE1))
					goto err;
			} else if (target->devices[i].device_instance == 0) {
				if ((target->devices[i].device_mode !=
						SND_SST_DEV_MODE_PCM_MODE2)
					&& (target->devices[i].device_mode !=
						SND_SST_DEV_MODE_PCM_MODE4_I2S)
					&& (target->devices[i].device_mode !=
						SND_SST_DEV_MODE_PCM_MODE1))
					goto err;
				if (target->devices[i].pcm_params.sfreq != 8000
				|| target->devices[i].pcm_params.num_chan != 1
				|| target->devices[i].pcm_params.pcm_wd_sz !=
									16)
					goto err;
			} else {
err:
				pr_err("i/p params incorrect\n");
				return -EINVAL;
			}
		}
	}
    return retval;
}

/**
 * sst_target_device_select - This function sets the target device configurations
 *
 * @target: this parameter holds the configurations to be set
 *
 * This function is called when the user layer wants to change the target
 * device's configurations
 */

int sst_target_device_select(struct snd_sst_target_device *target)
{
	int retval, i, prepare_count = 0;

	pr_debug("Target Device Select\n");

	if (target->device_route < 0 || target->device_route > 2) {
		pr_err("device route is invalid\n");
		return -EINVAL;
	}

	if (target->device_route != 0) {
		pr_err("Unsupported config\n");
		return -EIO;
	}
	retval = sst_target_device_validate(target);
	if (retval)
		return retval;

	retval = sst_send_target(target);
	if (retval)
		return retval;
	for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) {
		if (target->devices[i].action == SND_SST_PORT_ACTIVATE) {
			pr_debug("activate called in %d\n", i);
			retval = sst_parse_target(&target->devices[i]);
			if (retval)
				return retval;
		} else if (target->devices[i].action == SND_SST_PORT_PREPARE) {
			pr_debug("PREPARE in %d, Forwarding\n", i);
			retval = sst_parse_target(&target->devices[i]);
			if (retval) {
				pr_err("Parse Target fail %d\n", retval);
				return retval;
			}
			pr_debug("Parse Target successful %d\n", retval);
			if (target->devices[i].device_type ==
						SND_SST_DEVICE_PCM)
				prepare_count++;
		}
	}
	if (target->devices[0].action == SND_SST_PORT_PREPARE &&
		prepare_count == 0)
			sst_drv_ctx->scard_ops->power_down_pmic();

	return retval;
}
#ifdef CONFIG_MRST_RAR_HANDLER
/*This function gets the physical address of the secure memory from the handle*/
static inline int sst_get_RAR(struct RAR_buffer *buffers, int count)
{
	int retval = 0, rar_status = 0;

	rar_status = rar_handle_to_bus(buffers, count);

	if (count != rar_status) {
		pr_err("The rar CALL Failed");
		retval = -EIO;
	}
	if (buffers->info.type != RAR_TYPE_AUDIO) {
		pr_err("Invalid RAR type\n");
		return -EINVAL;
	}
	return retval;
}

#endif

/* This function creates the scatter gather list to be sent to firmware to
capture/playback data*/
static int sst_create_sg_list(struct stream_info *stream,
		struct sst_frame_info *sg_list)
{
	struct sst_stream_bufs *kbufs = NULL;
#ifdef CONFIG_MRST_RAR_HANDLER
	struct RAR_buffer rar_buffers;
	int retval = 0;
#endif
	int i = 0;
	list_for_each_entry(kbufs, &stream->bufs, node) {
		if (kbufs->in_use == false) {
#ifdef CONFIG_MRST_RAR_HANDLER
			if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
				pr_debug("DRM playback handling\n");
				rar_buffers.info.handle = (__u32)kbufs->addr;
				rar_buffers.info.size = kbufs->size;
				pr_debug("rar handle 0x%x size=0x%x\n",
					rar_buffers.info.handle,
					rar_buffers.info.size);
				retval =  sst_get_RAR(&rar_buffers, 1);

				if (retval)
					return retval;
				sg_list->addr[i].addr = rar_buffers.bus_address;
				/* rar_buffers.info.size; */
				sg_list->addr[i].size = (__u32)kbufs->size;
				pr_debug("phyaddr[%d] 0x%x Size:0x%x\n"
					, i, sg_list->addr[i].addr,
					sg_list->addr[i].size);
			}
#endif
			if (stream->ops != STREAM_OPS_PLAYBACK_DRM) {
				sg_list->addr[i].addr =
					virt_to_phys((void *)
						kbufs->addr + kbufs->offset);
				sg_list->addr[i].size = kbufs->size;
				pr_debug("phyaddr[%d]:0x%x Size:0x%x\n"
				, i , sg_list->addr[i].addr, kbufs->size);
			}
			stream->curr_bytes += sg_list->addr[i].size;
			kbufs->in_use = true;
			i++;
		}
		if (i >= MAX_NUM_SCATTER_BUFFERS)
			break;
	}

	sg_list->num_entries = i;
	pr_debug("sg list entries = %d\n", sg_list->num_entries);
	return i;
}


/**
 * sst_play_frame - Send msg for sending stream frames
 *
 * @str_id:	ID of stream
 *
 * This function is called to send data to be played out
 * to the firmware
 */
int sst_play_frame(int str_id)
{
	int i = 0, retval = 0;
	struct ipc_post *msg = NULL;
	struct sst_frame_info sg_list = {0};
	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
	struct stream_info *stream;

	pr_debug("play frame for %d\n", str_id);
	retval = sst_validate_strid(str_id);
	if (retval)
		return retval;

	stream = &sst_drv_ctx->streams[str_id];
	/* clear prev sent buffers */
	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
		if (kbufs->in_use == true) {
			spin_lock(&stream->pcm_lock);
			list_del(&kbufs->node);
			spin_unlock(&stream->pcm_lock);
			kfree(kbufs);
		}
	}
	/* update bytes sent */
	stream->cumm_bytes += stream->curr_bytes;
	stream->curr_bytes = 0;
	if (list_empty(&stream->bufs)) {
		/* no user buffer available */
		pr_debug("Null buffer stream status %d\n", stream->status);
		stream->prev = stream->status;
		stream->status = STREAM_INIT;
		pr_debug("new stream status = %d\n", stream->status);
		if (stream->need_draining == true) {
			pr_debug("draining stream\n");
			if (sst_create_short_msg(&msg)) {
				pr_err("mem allocation failed\n");
				return -ENOMEM;
			}
			sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM,
						0, str_id);
			spin_lock(&sst_drv_ctx->list_spin_lock);
			list_add_tail(&msg->node,
					&sst_drv_ctx->ipc_dispatch_list);
			spin_unlock(&sst_drv_ctx->list_spin_lock);
			sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
		} else if (stream->data_blk.on == true) {
			pr_debug("user list empty.. wake\n");
			/* unblock */
			stream->data_blk.ret_code = 0;
			stream->data_blk.condition = true;
			stream->data_blk.on = false;
			wake_up(&sst_drv_ctx->wait_queue);
		}
		return 0;
	}

	/* create list */
	i = sst_create_sg_list(stream, &sg_list);

	/* post msg */
	if (sst_create_large_msg(&msg))
		return -ENOMEM;

	sst_fill_header(&msg->header, IPC_IA_PLAY_FRAMES, 1, str_id);
	msg->header.part.data = sizeof(u32) + sizeof(sg_list);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	return 0;

}

/**
 * sst_capture_frame - Send msg for sending stream frames
 *
 * @str_id:	ID of stream
 *
 * This function is called to capture data from the firmware
 */
int sst_capture_frame(int str_id)
{
	int i = 0, retval = 0;
	struct ipc_post *msg = NULL;
	struct sst_frame_info sg_list = {0};
	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
	struct stream_info *stream;


	pr_debug("capture frame for %d\n", str_id);
	retval = sst_validate_strid(str_id);
	if (retval)
		return retval;
	stream = &sst_drv_ctx->streams[str_id];
	/* clear prev sent buffers */
	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
		if (kbufs->in_use == true) {
			list_del(&kbufs->node);
			kfree(kbufs);
			pr_debug("del node\n");
		}
	}
	if (list_empty(&stream->bufs)) {
		/* no user buffer available */
		pr_debug("Null buffer!!!!stream status %d\n",
			       stream->status);
		stream->prev = stream->status;
		stream->status = STREAM_INIT;
		pr_debug("new stream status = %d\n",
			       stream->status);
		if (stream->data_blk.on == true) {
			pr_debug("user list empty.. wake\n");
			/* unblock */
			stream->data_blk.ret_code = 0;
			stream->data_blk.condition = true;
			stream->data_blk.on = false;
			wake_up(&sst_drv_ctx->wait_queue);

		}
		return 0;
	}
	/* create new sg list */
	i = sst_create_sg_list(stream, &sg_list);

	/* post msg */
	if (sst_create_large_msg(&msg))
		return -ENOMEM;

	sst_fill_header(&msg->header, IPC_IA_CAPT_FRAMES, 1, str_id);
	msg->header.part.data = sizeof(u32) + sizeof(sg_list);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), &sg_list, sizeof(sg_list));
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);


	/*update bytes recevied*/
	stream->cumm_bytes += stream->curr_bytes;
	stream->curr_bytes = 0;

    pr_debug("Cum bytes  = %d\n", stream->cumm_bytes);
	return 0;
}

/*This function is used to calculate the minimum size of input buffers given*/
static unsigned int calculate_min_size(struct snd_sst_buffs *bufs)
{
	int i, min_val = bufs->buff_entry[0].size;
	for (i = 1 ; i < bufs->entries; i++) {
		if (bufs->buff_entry[i].size < min_val)
			min_val = bufs->buff_entry[i].size;
	}
	pr_debug("min_val = %d\n", min_val);
	return min_val;
}

static unsigned int calculate_max_size(struct snd_sst_buffs *bufs)
{
	int i, max_val = bufs->buff_entry[0].size;
	for (i = 1 ; i < bufs->entries; i++) {
		if (bufs->buff_entry[i].size > max_val)
			max_val = bufs->buff_entry[i].size;
	}
	pr_debug("max_val = %d\n", max_val);
	return max_val;
}

/*This function is used to allocate input and output buffers to be sent to
the firmware that will take encoded data and return decoded data*/
static int sst_allocate_decode_buf(struct stream_info *str_info,
				struct snd_sst_dbufs *dbufs,
				unsigned int cum_input_given,
				unsigned int cum_output_given)
{
#ifdef CONFIG_MRST_RAR_HANDLER
	if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {

		if (dbufs->ibufs->type == SST_BUF_RAR  &&
			dbufs->obufs->type == SST_BUF_RAR) {
			if (dbufs->ibufs->entries == dbufs->obufs->entries)
				return 0;
			else {
				pr_err("RAR entries dont match\n");
				 return -EINVAL;
			}
		} else
			str_info->decode_osize = cum_output_given;
		return 0;

	}
#endif
	if (!str_info->decode_ibuf) {
		pr_debug("no i/p buffers, trying full size\n");
		str_info->decode_isize = cum_input_given;
		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
						GFP_KERNEL);
		str_info->idecode_alloc = str_info->decode_isize;
	}
	if (!str_info->decode_ibuf) {
		pr_debug("buff alloc failed, try max size\n");
		str_info->decode_isize = calculate_max_size(dbufs->ibufs);
		str_info->decode_ibuf = kzalloc(
				str_info->decode_isize, GFP_KERNEL);
		str_info->idecode_alloc = str_info->decode_isize;
	}
	if (!str_info->decode_ibuf) {
		pr_debug("buff alloc failed, try min size\n");
		str_info->decode_isize = calculate_min_size(dbufs->ibufs);
		str_info->decode_ibuf = kzalloc(str_info->decode_isize,
						GFP_KERNEL);
		if (!str_info->decode_ibuf) {
			pr_err("mem allocation failed\n");
			return -ENOMEM;
		}
		str_info->idecode_alloc = str_info->decode_isize;
	}
	str_info->decode_osize = cum_output_given;
	if (str_info->decode_osize > sst_drv_ctx->mmap_len)
		str_info->decode_osize = sst_drv_ctx->mmap_len;
	return 0;
}

/*This function is used to send the message to firmware to decode the data*/
static int sst_send_decode_mess(int str_id, struct stream_info *str_info,
				struct snd_sst_decode_info *dec_info)
{
	struct ipc_post *msg = NULL;
	int retval = 0;

	pr_debug("SST DBG:sst_set_mute:called\n");

	if (str_info->decode_ibuf_type == SST_BUF_RAR) {
#ifdef CONFIG_MRST_RAR_HANDLER
			dec_info->frames_in.addr[0].addr =
				(unsigned long)str_info->decode_ibuf;
			dec_info->frames_in.addr[0].size =
							str_info->decode_isize;
#endif

	} else {
		dec_info->frames_in.addr[0].addr = virt_to_phys((void *)
					str_info->decode_ibuf);
		dec_info->frames_in.addr[0].size = str_info->decode_isize;
	}


	if (str_info->decode_obuf_type == SST_BUF_RAR) {
#ifdef CONFIG_MRST_RAR_HANDLER
		dec_info->frames_out.addr[0].addr =
				(unsigned long)str_info->decode_obuf;
		dec_info->frames_out.addr[0].size = str_info->decode_osize;
#endif

	} else {
		dec_info->frames_out.addr[0].addr = virt_to_phys((void *)
						str_info->decode_obuf) ;
		dec_info->frames_out.addr[0].size = str_info->decode_osize;
	}

	dec_info->frames_in.num_entries = 1;
	dec_info->frames_out.num_entries = 1;
	dec_info->frames_in.rsrvd = 0;
	dec_info->frames_out.rsrvd = 0;
	dec_info->input_bytes_consumed = 0;
	dec_info->output_bytes_produced = 0;
	if (sst_create_large_msg(&msg)) {
		pr_err("message creation failed\n");
		return -ENOMEM;
	}

	sst_fill_header(&msg->header, IPC_IA_DECODE_FRAMES, 1, str_id);
	msg->header.part.data = sizeof(u32) + sizeof(*dec_info);
	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
	memcpy(msg->mailbox_data + sizeof(u32), dec_info,
			sizeof(*dec_info));
	spin_lock(&sst_drv_ctx->list_spin_lock);
	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
	spin_unlock(&sst_drv_ctx->list_spin_lock);
	str_info->data_blk.condition = false;
	str_info->data_blk.ret_code = 0;
	str_info->data_blk.on = true;
	str_info->data_blk.data = dec_info;
	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
	retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
	return retval;
}

#ifdef CONFIG_MRST_RAR_HANDLER
static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
			struct snd_sst_dbufs *dbufs,
			int *input_index, int *in_copied,
			int *input_index_valid_size, int *new_entry_flag)
{
	int retval = 0, i;

	if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
		struct RAR_buffer rar_buffers;
		__u32 info;
		retval = copy_from_user((void *) &info,
				dbufs->ibufs->buff_entry[i].buffer,
				sizeof(__u32));
		if (retval) {
			pr_err("cpy from user fail\n");
			return -EAGAIN;
		}
		rar_buffers.info.type = dbufs->ibufs->type;
		rar_buffers.info.size = dbufs->ibufs->buff_entry[i].size;
		rar_buffers.info.handle =  info;
		pr_debug("rar in DnR(input buffer function)=0x%x size=0x%x",
				rar_buffers.info.handle,
				rar_buffers.info.size);
		retval =  sst_get_RAR(&rar_buffers, 1);
		if (retval) {
			pr_debug("SST ERR: RAR API failed\n");
			return retval;
		}
		str_info->decode_ibuf =
		(void *) ((unsigned long) rar_buffers.bus_address);
		pr_debug("RAR buf addr in DnR (input buffer function)0x%lu",
				 (unsigned long) str_info->decode_ibuf);
		pr_debug("rar in DnR decode function/output b_add rar =0x%lu",
				(unsigned long) rar_buffers.bus_address);
		*input_index = i + 1;
		str_info->decode_isize = dbufs->ibufs->buff_entry[i].size;
		str_info->decode_ibuf_type = dbufs->ibufs->type;
		*in_copied = str_info->decode_isize;
	}
	return retval;
}
#endif
/*This function is used to prepare the kernel input buffers with contents
before sending for decode*/
static int sst_prepare_input_buffers(struct stream_info *str_info,
			struct snd_sst_dbufs *dbufs,
			int *input_index, int *in_copied,
			int *input_index_valid_size, int *new_entry_flag)
{
	int i, cpy_size, retval = 0;

	pr_debug("input_index = %d, input entries = %d\n",
			 *input_index, dbufs->ibufs->entries);
	for (i = *input_index; i < dbufs->ibufs->entries; i++) {
#ifdef CONFIG_MRST_RAR_HANDLER
		retval = sst_prepare_input_buffers_rar(str_info,
			dbufs, input_index, in_copied,
				input_index_valid_size, new_entry_flag);
		if (retval) {
			pr_err("In prepare input buffers for RAR\n");
			return -EIO;
		}
#endif
		*input_index = i;
		if (*input_index_valid_size == 0)
			*input_index_valid_size =
				dbufs->ibufs->buff_entry[i].size;
		pr_debug("inout addr = %p, size = %d\n",
			dbufs->ibufs->buff_entry[i].buffer,
			*input_index_valid_size);
		pr_debug("decode_isize = %d, in_copied %d\n",
			str_info->decode_isize, *in_copied);
		if (*input_index_valid_size <=
					(str_info->decode_isize - *in_copied))
			cpy_size = *input_index_valid_size;
		else
			cpy_size = str_info->decode_isize - *in_copied;

		pr_debug("cpy size = %d\n", cpy_size);
		if (!dbufs->ibufs->buff_entry[i].buffer) {
			pr_err("i/p buffer is null\n");
			return -EINVAL;
		}
		pr_debug("Try copy To %p, From %p, size %d\n",
				str_info->decode_ibuf + *in_copied,
				dbufs->ibufs->buff_entry[i].buffer, cpy_size);

		retval =
		copy_from_user((void *)(str_info->decode_ibuf + *in_copied),
				(void *) dbufs->ibufs->buff_entry[i].buffer,
				cpy_size);
		if (retval) {
			pr_err("copy from user failed\n");
			return -EIO;
		}
		*in_copied += cpy_size;
		*input_index_valid_size -= cpy_size;
		pr_debug("in buff size = %d, in_copied = %d\n",
			*input_index_valid_size, *in_copied);
		if (*input_index_valid_size != 0) {
			pr_debug("more input buffers left\n");
			dbufs->ibufs->buff_entry[i].buffer += cpy_size;
			break;
		}
		if (*in_copied == str_info->decode_isize &&
			*input_index_valid_size == 0 &&
			(i+1) <= dbufs->ibufs->entries) {
			pr_debug("all input buffers copied\n");
			*new_entry_flag = true;
			*input_index = i + 1;
			break;
		}
	}
	return retval;
}

/* This function is used to copy the decoded data from kernel buffers to
the user output buffers with contents after decode*/
static int sst_prepare_output_buffers(struct stream_info *str_info,
			struct snd_sst_dbufs *dbufs,
			int *output_index, int output_size,
			int *out_copied)

{
	int i, cpy_size, retval = 0;
	pr_debug("output_index = %d, output entries = %d\n",
				*output_index,
				dbufs->obufs->entries);
	for (i = *output_index; i < dbufs->obufs->entries; i++) {
		*output_index = i;
		pr_debug("output addr = %p, size = %d\n",
			dbufs->obufs->buff_entry[i].buffer,
			dbufs->obufs->buff_entry[i].size);
		pr_debug("output_size = %d, out_copied = %d\n",
				output_size, *out_copied);
		if (dbufs->obufs->buff_entry[i].size <
				(output_size - *out_copied))
			cpy_size = dbufs->obufs->buff_entry[i].size;
		else
			cpy_size = output_size - *out_copied;
		pr_debug("cpy size = %d\n", cpy_size);
		pr_debug("Try copy To: %p, From %p, size %d\n",
				dbufs->obufs->buff_entry[i].buffer,
				sst_drv_ctx->mmap_mem + *out_copied,
				cpy_size);
		retval = copy_to_user(dbufs->obufs->buff_entry[i].buffer,
					sst_drv_ctx->mmap_mem + *out_copied,
					cpy_size);
		if (retval) {
			pr_err("copy to user failed\n");
			return -EIO;
		} else
			pr_debug("copy to user passed\n");
		*out_copied += cpy_size;
		dbufs->obufs->buff_entry[i].size -= cpy_size;
		pr_debug("o/p buff size %d, out_copied %d\n",
			dbufs->obufs->buff_entry[i].size, *out_copied);
		if (dbufs->obufs->buff_entry[i].size != 0) {
			*output_index = i;
			dbufs->obufs->buff_entry[i].buffer += cpy_size;
			break;
		} else if (*out_copied == output_size) {
			*output_index = i + 1;
			break;
		}
	}
	return retval;
}

/**
 * sst_decode - Send msg for decoding frames
 *
 * @str_id: ID of stream
 * @dbufs: param that holds the user input and output buffers and size
 *
 * This function is called to decode data from the firmware
 */
int sst_decode(int str_id, struct snd_sst_dbufs *dbufs)
{
	int retval = 0, i;
	unsigned long long total_input = 0 , total_output = 0;
	unsigned int cum_input_given = 0 , cum_output_given = 0;
	int copy_in_done = false, copy_out_done = false;
	int input_index = 0, output_index = 0;
	int input_index_valid_size = 0;
	int in_copied, out_copied;
	int new_entry_flag;
	u64 output_size;
	struct stream_info *str_info;
	struct snd_sst_decode_info dec_info;
	unsigned long long input_bytes, output_bytes;

	sst_drv_ctx->scard_ops->power_down_pmic();
	pr_debug("Powering_down_PMIC...\n");

	retval = sst_validate_strid(str_id);
	if (retval)
		return retval;

	str_info = &sst_drv_ctx->streams[str_id];
	if (str_info->status != STREAM_INIT) {
		pr_err("invalid stream state = %d\n",
			       str_info->status);
		return -EINVAL;
	}

	str_info->prev = str_info->status;
	str_info->status = STREAM_DECODE;

	for (i = 0; i < dbufs->ibufs->entries; i++)
		cum_input_given += dbufs->ibufs->buff_entry[i].size;
	for (i = 0; i < dbufs->obufs->entries; i++)
		cum_output_given += dbufs->obufs->buff_entry[i].size;

	/* input and output buffer allocation */
	retval =  sst_allocate_decode_buf(str_info, dbufs,
				cum_input_given, cum_output_given);
	if (retval) {
		pr_err("mem allocation failed, abort!!!\n");
		retval = -ENOMEM;
		goto finish;
	}

	str_info->decode_isize = str_info->idecode_alloc;
	str_info->decode_ibuf_type = dbufs->ibufs->type;
	str_info->decode_obuf_type = dbufs->obufs->type;

	while ((copy_out_done == false) && (copy_in_done == false)) {
		in_copied = 0;
		new_entry_flag = false;
		retval = sst_prepare_input_buffers(str_info,\
			dbufs, &input_index, &in_copied,
			&input_index_valid_size, &new_entry_flag);
		if (retval) {
			pr_err("prepare in buffers failed\n");
			goto finish;
		}

		if (str_info->ops != STREAM_OPS_PLAYBACK_DRM)
			str_info->decode_obuf = sst_drv_ctx->mmap_mem;

#ifdef CONFIG_MRST_RAR_HANDLER
		else {
			if (dbufs->obufs->type == SST_BUF_RAR) {
				struct RAR_buffer rar_buffers;
				__u32 info;

				pr_debug("DRM");
				retval = copy_from_user((void *) &info,
						dbufs->obufs->
						buff_entry[output_index].buffer,
						sizeof(__u32));

				rar_buffers.info.size = dbufs->obufs->
					buff_entry[output_index].size;
				rar_buffers.info.handle =  info;
				retval =  sst_get_RAR(&rar_buffers, 1);
				if (retval)
					return retval;

				str_info->decode_obuf = (void *)((unsigned long)
						rar_buffers.bus_address);
				str_info->decode_osize = dbufs->obufs->
					buff_entry[output_index].size;
				str_info->decode_obuf_type = dbufs->obufs->type;
				pr_debug("DRM handling\n");
				pr_debug("o/p_add=0x%lu Size=0x%x\n",
					(unsigned long) str_info->decode_obuf,
					str_info->decode_osize);
			} else {
				str_info->decode_obuf = sst_drv_ctx->mmap_mem;
				str_info->decode_osize = dbufs->obufs->
					buff_entry[output_index].size;

			}
		}
#endif
		if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
			if (str_info->decode_isize > in_copied) {
				str_info->decode_isize = in_copied;
				pr_debug("i/p size = %d\n",
						str_info->decode_isize);
			}
		}


		retval = sst_send_decode_mess(str_id, str_info, &dec_info);
		if (retval || dec_info.input_bytes_consumed == 0) {
			pr_err("SST ERR: mess failed or no input consumed\n");
			goto finish;
		}
		input_bytes = dec_info.input_bytes_consumed;
		output_bytes = dec_info.output_bytes_produced;

		pr_debug("in_copied=%d, con=%lld, prod=%lld\n",
			in_copied, input_bytes, output_bytes);
		if (dbufs->obufs->type == SST_BUF_RAR) {
			output_index += 1;
			if (output_index == dbufs->obufs->entries) {
				copy_in_done = true;
				pr_debug("all i/p cpy done\n");
			}
			total_output += output_bytes;
		} else {
			out_copied = 0;
			output_size = output_bytes;
			retval = sst_prepare_output_buffers(str_info, dbufs,
				&output_index, output_size, &out_copied);
			if (retval) {
				pr_err("prep out buff fail\n");
				goto finish;
			}
			if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) {
				if (in_copied != input_bytes) {
					int bytes_left = in_copied -
								input_bytes;
					pr_debug("bytes %d\n",
							bytes_left);
					if (new_entry_flag == true)
						input_index--;
					while (bytes_left) {
						struct snd_sst_buffs *ibufs;
						struct snd_sst_buff_entry
								*buff_entry;
						unsigned int size_sent;

						ibufs = dbufs->ibufs;
						buff_entry =
						&ibufs->buff_entry[input_index];
						size_sent = buff_entry->size -\
							input_index_valid_size;
						if (bytes_left == size_sent) {
								bytes_left = 0;
						} else if (bytes_left <
								size_sent) {
							buff_entry->buffer +=
							 (size_sent -
								bytes_left);
							buff_entry->size -=
							 (size_sent -
								bytes_left);
							bytes_left = 0;
						} else {
							bytes_left -= size_sent;
							input_index--;
							input_index_valid_size =
									0;
						}
					}

				}
			}

			total_output += out_copied;
			if (str_info->decode_osize != out_copied) {
				str_info->decode_osize -= out_copied;
				pr_debug("output size modified = %d\n",
						str_info->decode_osize);
			}
		}
		total_input += input_bytes;

		if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
			if (total_input == cum_input_given)
				copy_in_done = true;
			copy_out_done = true;

		} else {
			if (total_output == cum_output_given) {
				copy_out_done = true;
				pr_debug("all o/p cpy done\n");
			}

			if (total_input == cum_input_given) {
				copy_in_done = true;
				pr_debug("all i/p cpy done\n");
			}
		}

		pr_debug("copy_out = %d, copy_in = %d\n",
				copy_out_done, copy_in_done);
	}

finish:
	dbufs->input_bytes_consumed = total_input;
	dbufs->output_bytes_produced = total_output;
	str_info->status = str_info->prev;
	str_info->prev = STREAM_DECODE;
	kfree(str_info->decode_ibuf);
	str_info->decode_ibuf = NULL;
	return retval;
}
