/*
 *  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>
 *  Jeeja KP <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 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/pci.h>
#include <linux/fs.h>
#include <linux/uio.h>
#include <linux/aio.h>
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/pm_runtime.h>
#include <linux/ioctl.h>
#ifdef CONFIG_MRST_RAR_HANDLER
#include <linux/rar_register.h>
#include "../../../drivers/staging/memrar/memrar.h"
#endif
#include "intel_sst.h"
#include "intel_sst_ioctl.h"
#include "intel_sst_fw_ipc.h"
#include "intel_sst_common.h"

#define AM_MODULE 1
#define STREAM_MODULE 0


/**
* intel_sst_check_device - checks SST device
*
* This utility function checks the state of SST device and downlaods FW if
* not done, or resumes the device if suspended
*/

static int intel_sst_check_device(void)
{
	int retval = 0;
	if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) {
		pr_warn("Sound card not available\n");
		return -EIO;
	}
	if (sst_drv_ctx->sst_state == SST_SUSPENDED) {
		pr_debug("Resuming from Suspended state\n");
		retval = intel_sst_resume(sst_drv_ctx->pci);
		if (retval) {
			pr_debug("Resume Failed= %#x,abort\n", retval);
			return retval;
		}
	}

	if (sst_drv_ctx->sst_state == SST_UN_INIT) {
		/* FW is not downloaded */
		retval = sst_download_fw();
		if (retval)
			return -ENODEV;
		if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
			retval = sst_drv_ctx->rx_time_slot_status;
			if (retval != RX_TIMESLOT_UNINIT
					&& sst_drv_ctx->pmic_vendor != SND_NC)
				sst_enable_rx_timeslot(retval);
		}
	}
	return 0;
}

/**
 * intel_sst_open - opens a handle to driver
 *
 * @i_node:	inode structure
 * @file_ptr:pointer to file
 *
 * This function is called by OS when a user space component
 * tries to get a driver handle. Only one handle at a time
 * will be allowed
 */
int intel_sst_open(struct inode *i_node, struct file *file_ptr)
{
	unsigned int retval;

	mutex_lock(&sst_drv_ctx->stream_lock);
	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);
	retval = intel_sst_check_device();
	if (retval) {
		pm_runtime_put(&sst_drv_ctx->pci->dev);
		mutex_unlock(&sst_drv_ctx->stream_lock);
		return retval;
	}

	if (sst_drv_ctx->encoded_cnt < MAX_ENC_STREAM) {
		struct ioctl_pvt_data *data =
			kzalloc(sizeof(struct ioctl_pvt_data), GFP_KERNEL);
		if (!data) {
			pm_runtime_put(&sst_drv_ctx->pci->dev);
			mutex_unlock(&sst_drv_ctx->stream_lock);
			return -ENOMEM;
		}

		sst_drv_ctx->encoded_cnt++;
		mutex_unlock(&sst_drv_ctx->stream_lock);
		data->pvt_id = sst_assign_pvt_id(sst_drv_ctx);
		data->str_id = 0;
		file_ptr->private_data = (void *)data;
		pr_debug("pvt_id handle = %d!\n", data->pvt_id);
	} else {
		retval = -EUSERS;
		pm_runtime_put(&sst_drv_ctx->pci->dev);
		mutex_unlock(&sst_drv_ctx->stream_lock);
	}
	return retval;
}

/**
 * intel_sst_open_cntrl - opens a handle to driver
 *
 * @i_node:	inode structure
 * @file_ptr:pointer to file
 *
 * This function is called by OS when a user space component
 * tries to get a driver handle to /dev/intel_sst_control.
 * Only one handle at a time will be allowed
 * This is for control operations only
 */
int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr)
{
	unsigned int retval;

	/* audio manager open */
	mutex_lock(&sst_drv_ctx->stream_lock);
	pm_runtime_get_sync(&sst_drv_ctx->pci->dev);
	retval = intel_sst_check_device();
	if (retval) {
		pm_runtime_put(&sst_drv_ctx->pci->dev);
		mutex_unlock(&sst_drv_ctx->stream_lock);
		return retval;
	}

	if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) {
		sst_drv_ctx->am_cnt++;
		pr_debug("AM handle opened...\n");
		file_ptr->private_data = NULL;
	} else {
		retval = -EACCES;
		pm_runtime_put(&sst_drv_ctx->pci->dev);
	}

	mutex_unlock(&sst_drv_ctx->stream_lock);
	return retval;
}

/**
 * intel_sst_release - releases a handle to driver
 *
 * @i_node:	inode structure
 * @file_ptr:	pointer to file
 *
 * This function is called by OS when a user space component
 * tries to release a driver handle.
 */
int intel_sst_release(struct inode *i_node, struct file *file_ptr)
{
	struct ioctl_pvt_data *data = file_ptr->private_data;

	pr_debug("Release called, closing app handle\n");
	mutex_lock(&sst_drv_ctx->stream_lock);
	sst_drv_ctx->encoded_cnt--;
	sst_drv_ctx->stream_cnt--;
	pm_runtime_put(&sst_drv_ctx->pci->dev);
	mutex_unlock(&sst_drv_ctx->stream_lock);
	free_stream_context(data->str_id);
	kfree(data);
	return 0;
}

int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr)
{
	/* audio manager close */
	mutex_lock(&sst_drv_ctx->stream_lock);
	sst_drv_ctx->am_cnt--;
	pm_runtime_put(&sst_drv_ctx->pci->dev);
	mutex_unlock(&sst_drv_ctx->stream_lock);
	pr_debug("AM handle closed\n");
	return 0;
}

/**
* intel_sst_mmap - mmaps a kernel buffer to user space for copying data
*
* @vma:		vm area structure instance
* @file_ptr:	pointer to file
*
* This function is called by OS when a user space component
* tries to get mmap memory from driver
*/
int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma)
{
	int retval, length;
	struct ioctl_pvt_data *data =
		(struct ioctl_pvt_data *)file_ptr->private_data;
	int str_id = data->str_id;
	void *mem_area;

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

	length = vma->vm_end - vma->vm_start;
	pr_debug("called for stream %d length 0x%x\n", str_id, length);

	if (length > sst_drv_ctx->mmap_len)
		return -ENOMEM;
	if (!sst_drv_ctx->mmap_mem)
		return -EIO;

	/* round it up to the page bondary  */
	/*mem_area = (void *)((((unsigned long)sst_drv_ctx->mmap_mem)
				+ PAGE_SIZE - 1) & PAGE_MASK);*/
	mem_area = (void *) PAGE_ALIGN((unsigned int) sst_drv_ctx->mmap_mem);

	/* map the whole physically contiguous area in one piece  */
	retval = remap_pfn_range(vma,
			vma->vm_start,
			virt_to_phys((void *)mem_area) >> PAGE_SHIFT,
			length,
			vma->vm_page_prot);
	if (retval)
		sst_drv_ctx->streams[str_id].mmapped = false;
	else
		sst_drv_ctx->streams[str_id].mmapped = true;

	pr_debug("mmap ret 0x%x\n", retval);
	return retval;
}

/* sets mmap data buffers to play/capture*/
static int intel_sst_mmap_play_capture(u32 str_id,
		struct snd_sst_mmap_buffs *mmap_buf)
{
	struct sst_stream_bufs *bufs;
	int retval, i;
	struct stream_info *stream;
	struct snd_sst_mmap_buff_entry *buf_entry;
	struct snd_sst_mmap_buff_entry *tmp_buf;

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

	stream = &sst_drv_ctx->streams[str_id];
	if (stream->mmapped != true)
		return -EIO;

	if (stream->status == STREAM_UN_INIT ||
		stream->status == STREAM_DECODE) {
		return -EBADRQC;
	}
	stream->curr_bytes = 0;
	stream->cumm_bytes = 0;

	tmp_buf = kcalloc(mmap_buf->entries, sizeof(*tmp_buf), GFP_KERNEL);
	if (!tmp_buf)
		return -ENOMEM;
	if (copy_from_user(tmp_buf, (void __user *)mmap_buf->buff,
			mmap_buf->entries * sizeof(*tmp_buf))) {
		retval = -EFAULT;
		goto out_free;
	}

	pr_debug("new buffers count %d status %d\n",
			mmap_buf->entries, stream->status);
	buf_entry = tmp_buf;
	for (i = 0; i < mmap_buf->entries; i++) {
		bufs = kzalloc(sizeof(*bufs), GFP_KERNEL);
		if (!bufs) {
			retval = -ENOMEM;
			goto out_free;
		}
		bufs->size = buf_entry->size;
		bufs->offset = buf_entry->offset;
		bufs->addr = sst_drv_ctx->mmap_mem;
		bufs->in_use = false;
		buf_entry++;
		/* locking here */
		mutex_lock(&stream->lock);
		list_add_tail(&bufs->node, &stream->bufs);
		mutex_unlock(&stream->lock);
	}

	mutex_lock(&stream->lock);
	stream->data_blk.condition = false;
	stream->data_blk.ret_code = 0;
	if (stream->status == STREAM_INIT &&
			stream->prev != STREAM_UN_INIT &&
			stream->need_draining != true) {
		stream->prev = stream->status;
		stream->status = STREAM_RUNNING;
		if (stream->ops == STREAM_OPS_PLAYBACK) {
			if (sst_play_frame(str_id) < 0) {
				pr_warn("play frames fail\n");
				mutex_unlock(&stream->lock);
				retval = -EIO;
				goto out_free;
			}
		} else if (stream->ops == STREAM_OPS_CAPTURE) {
			if (sst_capture_frame(str_id) < 0) {
				pr_warn("capture frame fail\n");
				mutex_unlock(&stream->lock);
				retval = -EIO;
				goto out_free;
			}
		}
	}
	mutex_unlock(&stream->lock);
	/* Block the call for reply */
	if (!list_empty(&stream->bufs)) {
		stream->data_blk.on = true;
		retval = sst_wait_interruptible(sst_drv_ctx,
					&stream->data_blk);
	}

	if (retval >= 0)
		retval = stream->cumm_bytes;
	pr_debug("end of play/rec ioctl bytes = %d!!\n", retval);

out_free:
	kfree(tmp_buf);
	return retval;
}

/*sets user data buffers to play/capture*/
static int intel_sst_play_capture(struct stream_info *stream, int str_id)
{
	int retval;

	stream->data_blk.ret_code = 0;
	stream->data_blk.on = true;
	stream->data_blk.condition = false;

	mutex_lock(&stream->lock);
	if (stream->status == STREAM_INIT && stream->prev != STREAM_UN_INIT) {
		/* stream is started */
		stream->prev = stream->status;
		stream->status = STREAM_RUNNING;
	}

	if (stream->status == STREAM_INIT && stream->prev == STREAM_UN_INIT) {
		/* stream is not started yet */
		pr_debug("Stream isn't in started state %d, prev %d\n",
			stream->status, stream->prev);
	} else if ((stream->status == STREAM_RUNNING ||
			stream->status == STREAM_PAUSED) &&
			stream->need_draining != true) {
		/* stream is started */
		if (stream->ops == STREAM_OPS_PLAYBACK ||
				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
			if (sst_play_frame(str_id) < 0) {
				pr_warn("play frames failed\n");
				mutex_unlock(&stream->lock);
				return -EIO;
			}
		} else if (stream->ops == STREAM_OPS_CAPTURE) {
			if (sst_capture_frame(str_id) < 0) {
				pr_warn("capture frames failed\n");
				mutex_unlock(&stream->lock);
				return -EIO;
			}
		}
	} else {
		mutex_unlock(&stream->lock);
		return -EIO;
	}
	mutex_unlock(&stream->lock);
	/* Block the call for reply */

	retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk);
	if (retval) {
		stream->status = STREAM_INIT;
		pr_debug("wait returned error...\n");
	}
	return retval;
}

/* fills kernel list with buffer addresses for SST DSP driver to process*/
static int snd_sst_fill_kernel_list(struct stream_info *stream,
			const struct iovec *iovec, unsigned long nr_segs,
			struct list_head *copy_to_list)
{
	struct sst_stream_bufs *stream_bufs;
	unsigned long index, mmap_len;
	unsigned char __user *bufp;
	unsigned long size, copied_size;
	int retval = 0, add_to_list = 0;
	static int sent_offset;
	static unsigned long sent_index;

	stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
	if (!stream_bufs)
		return -ENOMEM;
	stream_bufs->addr = sst_drv_ctx->mmap_mem;
#ifdef CONFIG_MRST_RAR_HANDLER
	if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
		for (index = stream->sg_index; index < nr_segs; index++) {
			__u32 rar_handle;
			struct sst_stream_bufs *stream_bufs =
				kzalloc(sizeof(*stream_bufs), GFP_KERNEL);

			stream->sg_index = index;
			if (!stream_bufs)
				return -ENOMEM;
			if (copy_from_user((void *) &rar_handle,
					iovec[index].iov_base,
					sizeof(__u32)))
				return -EFAULT;
			stream_bufs->addr = (char *)rar_handle;
			stream_bufs->in_use = false;
			stream_bufs->size = iovec[0].iov_len;
			/* locking here */
			mutex_lock(&stream->lock);
			list_add_tail(&stream_bufs->node, &stream->bufs);
			mutex_unlock(&stream->lock);
		}
		stream->sg_index = index;
		return retval;
	}
#endif
	mmap_len = sst_drv_ctx->mmap_len;
	stream_bufs->addr = sst_drv_ctx->mmap_mem;
	bufp = stream->cur_ptr;

	copied_size = 0;

	if (!stream->sg_index)
		sent_index = sent_offset = 0;

	for (index = stream->sg_index; index < nr_segs; index++) {
		stream->sg_index = index;
		if (!stream->cur_ptr)
			bufp = iovec[index].iov_base;

		size = ((unsigned long)iovec[index].iov_base
			+ iovec[index].iov_len) - (unsigned long) bufp;

		if ((copied_size + size) > mmap_len)
			size = mmap_len - copied_size;


		if (stream->ops == STREAM_OPS_PLAYBACK) {
			if (copy_from_user((void *)
					(stream_bufs->addr + copied_size),
					bufp, size)) {
				/* Clean up the list and return error code */
				retval = -EFAULT;
				break;
			}
		} else if (stream->ops == STREAM_OPS_CAPTURE) {
			struct snd_sst_user_cap_list *entry =
				kzalloc(sizeof(*entry), GFP_KERNEL);

			if (!entry) {
				kfree(stream_bufs);
				return -ENOMEM;
			}
			entry->iov_index = index;
			entry->iov_offset = (unsigned long) bufp -
					(unsigned long)iovec[index].iov_base;
			entry->offset = copied_size;
			entry->size = size;
			list_add_tail(&entry->node, copy_to_list);
		}

		stream->cur_ptr = bufp + size;

		if (((unsigned long)iovec[index].iov_base
				+ iovec[index].iov_len) <
				((unsigned long)iovec[index].iov_base)) {
			pr_debug("Buffer overflows\n");
			kfree(stream_bufs);
			return -EINVAL;
		}

		if (((unsigned long)iovec[index].iov_base
					+ iovec[index].iov_len) ==
					(unsigned long)stream->cur_ptr) {
			stream->cur_ptr = NULL;
			stream->sg_index++;
		}

		copied_size += size;
		pr_debug("copied_size - %lx\n", copied_size);
		if ((copied_size >= mmap_len) ||
				(stream->sg_index == nr_segs)) {
			add_to_list = 1;
		}

		if (add_to_list) {
			stream_bufs->in_use = false;
			stream_bufs->size = copied_size;
			/* locking here */
			mutex_lock(&stream->lock);
			list_add_tail(&stream_bufs->node, &stream->bufs);
			mutex_unlock(&stream->lock);
			break;
		}
	}
	return retval;
}

/* This function copies the captured data returned from SST DSP engine
 * to the user buffers*/
static int snd_sst_copy_userbuf_capture(struct stream_info *stream,
			const struct iovec *iovec,
			struct list_head *copy_to_list)
{
	struct snd_sst_user_cap_list *entry, *_entry;
	struct sst_stream_bufs *kbufs = NULL, *_kbufs;
	int retval = 0;

	/* copy sent buffers */
	pr_debug("capture stream copying to user now...\n");
	list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) {
		if (kbufs->in_use == true) {
			/* copy to user */
			list_for_each_entry_safe(entry, _entry,
						copy_to_list, node) {
				if (copy_to_user(iovec[entry->iov_index].iov_base + entry->iov_offset,
					     kbufs->addr + entry->offset,
					     entry->size)) {
					/* Clean up the list and return error */
					retval = -EFAULT;
					break;
				}
				list_del(&entry->node);
				kfree(entry);
			}
		}
	}
	pr_debug("end of cap copy\n");
	return retval;
}

/*
 * snd_sst_userbufs_play_cap - constructs the list from user buffers
 *
 * @iovec:pointer to iovec structure
 * @nr_segs:number entries in the iovec structure
 * @str_id:stream id
 * @stream:pointer to stream_info structure
 *
 * This function will traverse the user list and copy the data to the kernel
 * space buffers.
 */
static int snd_sst_userbufs_play_cap(const struct iovec *iovec,
			unsigned long nr_segs, unsigned int str_id,
			struct stream_info *stream)
{
	int retval;
	LIST_HEAD(copy_to_list);


	retval = snd_sst_fill_kernel_list(stream, iovec, nr_segs,
		       &copy_to_list);

	retval = intel_sst_play_capture(stream, str_id);
	if (retval < 0)
		return retval;

	if (stream->ops == STREAM_OPS_CAPTURE) {
		retval = snd_sst_copy_userbuf_capture(stream, iovec,
				&copy_to_list);
	}
	return retval;
}

/* This function is common function across read/write
  for user buffers called from system calls*/
static int intel_sst_read_write(unsigned int str_id, char __user *buf,
					size_t count)
{
	int retval;
	struct stream_info *stream;
	struct iovec iovec;
	unsigned long nr_segs;

	retval = sst_validate_strid(str_id);
	if (retval)
		return -EINVAL;
	stream = &sst_drv_ctx->streams[str_id];
	if (stream->mmapped == true) {
		pr_warn("user write and stream is mapped\n");
		return -EIO;
	}
	if (!count)
		return -EINVAL;
	stream->curr_bytes = 0;
	stream->cumm_bytes = 0;
	/* copy user buf details */
	pr_debug("new buffers %p, copy size %d, status %d\n" ,
			buf, (int) count, (int) stream->status);

	stream->buf_type = SST_BUF_USER_STATIC;
	iovec.iov_base = buf;
	iovec.iov_len  = count;
	nr_segs = 1;

	do {
		retval = snd_sst_userbufs_play_cap(
				&iovec, nr_segs, str_id, stream);
		if (retval < 0)
			break;

	} while (stream->sg_index < nr_segs);

	stream->sg_index = 0;
	stream->cur_ptr = NULL;
	if (retval >= 0)
		retval = stream->cumm_bytes;
	pr_debug("end of play/rec bytes = %d!!\n", retval);
	return retval;
}

/***
 * intel_sst_write - This function is called when user tries to play out data
 *
 * @file_ptr:pointer to file
 * @buf:user buffer to be played out
 * @count:size of tthe buffer
 * @offset:offset to start from
 *
 * writes the encoded data into DSP
 */
int intel_sst_write(struct file *file_ptr, const char __user *buf,
			size_t count, loff_t *offset)
{
	struct ioctl_pvt_data *data = file_ptr->private_data;
	int str_id = data->str_id;
	struct stream_info *stream = &sst_drv_ctx->streams[str_id];

	pr_debug("called for %d\n", str_id);
	if (stream->status == STREAM_UN_INIT ||
		stream->status == STREAM_DECODE) {
		return -EBADRQC;
	}
	return intel_sst_read_write(str_id, (char __user *)buf, count);
}

/*
 * intel_sst_aio_write - write buffers
 *
 * @kiocb:pointer to a structure containing file pointer
 * @iov:list of user buffer to be played out
 * @nr_segs:number of entries
 * @offset:offset to start from
 *
 * This function is called when user tries to play out multiple data buffers
 */
ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov,
			unsigned long nr_segs, loff_t  offset)
{
	int retval;
	struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
	int str_id = data->str_id;
	struct stream_info *stream;

	pr_debug("entry - %ld\n", nr_segs);

	if (is_sync_kiocb(kiocb) == false)
		return -EINVAL;

	pr_debug("called for str_id %d\n", str_id);
	retval = sst_validate_strid(str_id);
	if (retval)
		return -EINVAL;
	stream = &sst_drv_ctx->streams[str_id];
	if (stream->mmapped == true)
		return -EIO;
	if (stream->status == STREAM_UN_INIT ||
		stream->status == STREAM_DECODE) {
		return -EBADRQC;
	}
	stream->curr_bytes = 0;
	stream->cumm_bytes = 0;
	pr_debug("new segs %ld, offset %d, status %d\n" ,
			nr_segs, (int) offset, (int) stream->status);
	stream->buf_type = SST_BUF_USER_STATIC;
	do {
		retval = snd_sst_userbufs_play_cap(iov, nr_segs,
						str_id, stream);
		if (retval < 0)
			break;

	} while (stream->sg_index < nr_segs);

	stream->sg_index = 0;
	stream->cur_ptr = NULL;
	if (retval >= 0)
		retval = stream->cumm_bytes;
	pr_debug("end of play/rec bytes = %d!!\n", retval);
	return retval;
}

/*
 * intel_sst_read - read the encoded data
 *
 * @file_ptr: pointer to file
 * @buf: user buffer to be filled with captured data
 * @count: size of tthe buffer
 * @offset: offset to start from
 *
 * This function is called when user tries to capture data
 */
int intel_sst_read(struct file *file_ptr, char __user *buf,
			size_t count, loff_t *offset)
{
	struct ioctl_pvt_data *data = file_ptr->private_data;
	int str_id = data->str_id;
	struct stream_info *stream = &sst_drv_ctx->streams[str_id];

	pr_debug("called for %d\n", str_id);
	if (stream->status == STREAM_UN_INIT ||
			stream->status == STREAM_DECODE)
		return -EBADRQC;
	return intel_sst_read_write(str_id, buf, count);
}

/*
 * intel_sst_aio_read - aio read
 *
 * @kiocb: pointer to a structure containing file pointer
 * @iov: list of user buffer to be filled with captured
 * @nr_segs: number of entries
 * @offset: offset to start from
 *
 * This function is called when user tries to capture out multiple data buffers
 */
ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov,
			 unsigned long nr_segs, loff_t offset)
{
	int retval;
	struct ioctl_pvt_data *data = kiocb->ki_filp->private_data;
	int str_id = data->str_id;
	struct stream_info *stream;

	pr_debug("entry - %ld\n", nr_segs);

	if (is_sync_kiocb(kiocb) == false) {
		pr_debug("aio_read from user space is not allowed\n");
		return -EINVAL;
	}

	pr_debug("called for str_id %d\n", str_id);
	retval = sst_validate_strid(str_id);
	if (retval)
		return -EINVAL;
	stream = &sst_drv_ctx->streams[str_id];
	if (stream->mmapped == true)
		return -EIO;
	if (stream->status == STREAM_UN_INIT ||
			stream->status == STREAM_DECODE)
		return -EBADRQC;
	stream->curr_bytes = 0;
	stream->cumm_bytes = 0;

	pr_debug("new segs %ld, offset %d, status %d\n" ,
			nr_segs, (int) offset, (int) stream->status);
	stream->buf_type = SST_BUF_USER_STATIC;
	do {
		retval = snd_sst_userbufs_play_cap(iov, nr_segs,
						str_id, stream);
		if (retval < 0)
			break;

	} while (stream->sg_index < nr_segs);

	stream->sg_index = 0;
	stream->cur_ptr = NULL;
	if (retval >= 0)
		retval = stream->cumm_bytes;
	pr_debug("end of play/rec bytes = %d!!\n", retval);
	return retval;
}

/* sst_print_stream_params - prints the stream parameters (debug fn)*/
static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm)
{
	pr_debug("codec params:result = %d\n",
				get_prm->codec_params.result);
	pr_debug("codec params:stream = %d\n",
				get_prm->codec_params.stream_id);
	pr_debug("codec params:codec = %d\n",
				get_prm->codec_params.codec);
	pr_debug("codec params:ops = %d\n",
				get_prm->codec_params.ops);
	pr_debug("codec params:stream_type = %d\n",
				get_prm->codec_params.stream_type);
	pr_debug("pcmparams:sfreq = %d\n",
				get_prm->pcm_params.sfreq);
	pr_debug("pcmparams:num_chan = %d\n",
				get_prm->pcm_params.num_chan);
	pr_debug("pcmparams:pcm_wd_sz = %d\n",
				get_prm->pcm_params.pcm_wd_sz);
	return;
}

/**
 * sst_create_algo_ipc - create ipc msg for algorithm parameters
 *
 * @algo_params: Algorithm parameters
 * @msg: post msg pointer
 *
 * This function is called to create ipc msg
 */
int sst_create_algo_ipc(struct snd_ppp_params *algo_params,
					struct ipc_post **msg)
{
	if (sst_create_large_msg(msg))
		return -ENOMEM;
	sst_fill_header(&(*msg)->header,
			IPC_IA_ALG_PARAMS, 1, algo_params->str_id);
	(*msg)->header.part.data = sizeof(u32) +
			sizeof(*algo_params) + algo_params->size;
	memcpy((*msg)->mailbox_data, &(*msg)->header, sizeof(u32));
	memcpy((*msg)->mailbox_data + sizeof(u32),
				algo_params, sizeof(*algo_params));
	return 0;
}

/**
 * sst_send_algo_ipc - send ipc msg for algorithm parameters
 *
 * @msg: post msg pointer
 *
 * This function is called to send ipc msg
 */
int sst_send_algo_ipc(struct ipc_post **msg)
{
	sst_drv_ctx->ppp_params_blk.condition = false;
	sst_drv_ctx->ppp_params_blk.ret_code = 0;
	sst_drv_ctx->ppp_params_blk.on = true;
	sst_drv_ctx->ppp_params_blk.data = NULL;
	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 sst_wait_interruptible_timeout(sst_drv_ctx,
			&sst_drv_ctx->ppp_params_blk, SST_BLOCK_TIMEOUT);
}

/**
 * intel_sst_ioctl_dsp - recieves the device ioctl's
 *
 * @cmd:Ioctl cmd
 * @arg:data
 *
 * This function is called when a user space component
 * sends a DSP Ioctl to SST driver
 */
long intel_sst_ioctl_dsp(unsigned int cmd, unsigned long arg)
{
	int retval = 0;
	struct snd_ppp_params algo_params;
	struct snd_ppp_params *algo_params_copied;
	struct ipc_post *msg;

	switch (_IOC_NR(cmd)) {
	case _IOC_NR(SNDRV_SST_SET_ALGO):
		if (copy_from_user(&algo_params, (void __user *)arg,
							sizeof(algo_params)))
			return -EFAULT;
		if (algo_params.size > SST_MAILBOX_SIZE)
			return -EMSGSIZE;

		pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
			algo_params.algo_id, algo_params.str_id,
			algo_params.enable, algo_params.size);
		retval = sst_create_algo_ipc(&algo_params, &msg);
		if (retval)
			break;
		algo_params.reserved = 0;
		if (copy_from_user(msg->mailbox_data + sizeof(algo_params),
				algo_params.params, algo_params.size))
			return -EFAULT;

		retval = sst_send_algo_ipc(&msg);
		if (retval) {
			pr_debug("Error in sst_set_algo = %d\n", retval);
			retval = -EIO;
		}
		break;

	case _IOC_NR(SNDRV_SST_GET_ALGO):
		if (copy_from_user(&algo_params, (void __user *)arg,
							sizeof(algo_params)))
			return -EFAULT;
		pr_debug("Algo ID %d Str id %d Enable %d Size %d\n",
			algo_params.algo_id, algo_params.str_id,
			algo_params.enable, algo_params.size);
		retval = sst_create_algo_ipc(&algo_params, &msg);
		if (retval)
			break;
		algo_params.reserved = 1;
		retval = sst_send_algo_ipc(&msg);
		if (retval) {
			pr_debug("Error in sst_get_algo = %d\n", retval);
			retval = -EIO;
			break;
		}
		algo_params_copied = (struct snd_ppp_params *)
					sst_drv_ctx->ppp_params_blk.data;
		if (algo_params_copied->size > algo_params.size) {
			pr_debug("mem insufficient to copy\n");
			retval = -EMSGSIZE;
			goto free_mem;
		} else {
			char __user *tmp;

			if (copy_to_user(algo_params.params,
					algo_params_copied->params,
					algo_params_copied->size)) {
				retval = -EFAULT;
				goto free_mem;
			}
			tmp = (char __user *)arg + offsetof(
					struct snd_ppp_params, size);
			if (copy_to_user(tmp, &algo_params_copied->size,
						 sizeof(__u32))) {
				retval = -EFAULT;
				goto free_mem;
			}

		}
free_mem:
		kfree(algo_params_copied->params);
		kfree(algo_params_copied);
		break;
	}
	return retval;
}

/**
 * intel_sst_ioctl - receives the device ioctl's
 * @file_ptr:pointer to file
 * @cmd:Ioctl cmd
 * @arg:data
 *
 * This function is called by OS when a user space component
 * sends an Ioctl to SST driver
 */
long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg)
{
	int retval = 0;
	struct ioctl_pvt_data *data = NULL;
	int str_id = 0, minor = 0;

	data = file_ptr->private_data;
	if (data) {
		minor = 0;
		str_id = data->str_id;
	} else
		minor = 1;

	if (sst_drv_ctx->sst_state != SST_FW_RUNNING)
		return -EBUSY;

	switch (_IOC_NR(cmd)) {
	case _IOC_NR(SNDRV_SST_STREAM_PAUSE):
		pr_debug("IOCTL_PAUSE received for %d!\n", str_id);
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		retval = sst_pause_stream(str_id);
		break;

	case _IOC_NR(SNDRV_SST_STREAM_RESUME):
		pr_debug("SNDRV_SST_IOCTL_RESUME received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		retval = sst_resume_stream(str_id);
		break;

	case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): {
		struct snd_sst_params str_param;

		pr_debug("IOCTL_SET_PARAMS received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}

		if (copy_from_user(&str_param, (void __user *)arg,
				sizeof(str_param))) {
			retval = -EFAULT;
			break;
		}

		if (!str_id) {

			retval = sst_get_stream(&str_param);
			if (retval > 0) {
				struct stream_info *str_info;
				char __user *dest;

				sst_drv_ctx->stream_cnt++;
				data->str_id = retval;
				str_info = &sst_drv_ctx->streams[retval];
				str_info->src = SST_DRV;
				dest = (char __user *)arg + offsetof(struct snd_sst_params, stream_id);
				retval = copy_to_user(dest, &retval, sizeof(__u32));
				if (retval)
					retval = -EFAULT;
			} else {
				if (retval == -SST_ERR_INVALID_PARAMS)
					retval = -EINVAL;
			}
		} else {
			pr_debug("SET_STREAM_PARAMS received!\n");
			/* allocated set params only */
			retval = sst_set_stream_param(str_id, &str_param);
			/* Block the call for reply */
			if (!retval) {
				int sfreq = 0, word_size = 0, num_channel = 0;
				sfreq =	str_param.sparams.uc.pcm_params.sfreq;
				word_size = str_param.sparams.uc.pcm_params.pcm_wd_sz;
				num_channel = str_param.sparams.uc.pcm_params.num_chan;
				if (str_param.ops == STREAM_OPS_CAPTURE) {
					sst_drv_ctx->scard_ops->\
					set_pcm_audio_params(sfreq,
						word_size, num_channel);
				}
			}
		}
		break;
	}
	case _IOC_NR(SNDRV_SST_SET_VOL): {
		struct snd_sst_vol set_vol;

		if (copy_from_user(&set_vol, (void __user *)arg,
				sizeof(set_vol))) {
			pr_debug("copy failed\n");
			retval = -EFAULT;
			break;
		}
		pr_debug("SET_VOLUME recieved for %d!\n",
				set_vol.stream_id);
		if (minor == STREAM_MODULE && set_vol.stream_id == 0) {
			pr_debug("invalid operation!\n");
			retval = -EPERM;
			break;
		}
		retval = sst_set_vol(&set_vol);
		break;
	}
	case _IOC_NR(SNDRV_SST_GET_VOL): {
		struct snd_sst_vol get_vol;

		if (copy_from_user(&get_vol, (void __user *)arg,
				sizeof(get_vol))) {
			retval = -EFAULT;
			break;
		}
		pr_debug("IOCTL_GET_VOLUME recieved for stream = %d!\n",
				get_vol.stream_id);
		if (minor == STREAM_MODULE && get_vol.stream_id == 0) {
			pr_debug("invalid operation!\n");
			retval = -EPERM;
			break;
		}
		retval = sst_get_vol(&get_vol);
		if (retval) {
			retval = -EIO;
			break;
		}
		pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n",
				get_vol.stream_id, get_vol.volume,
				get_vol.ramp_duration, get_vol.ramp_type);
		if (copy_to_user((struct snd_sst_vol __user *)arg,
				&get_vol, sizeof(get_vol))) {
			retval = -EFAULT;
			break;
		}
		/*sst_print_get_vol_info(str_id, &get_vol);*/
		break;
	}

	case _IOC_NR(SNDRV_SST_MUTE): {
		struct snd_sst_mute set_mute;

		if (copy_from_user(&set_mute, (void __user *)arg,
				sizeof(set_mute))) {
			retval = -EFAULT;
			break;
		}
		pr_debug("SNDRV_SST_SET_VOLUME recieved for %d!\n",
			set_mute.stream_id);
		if (minor == STREAM_MODULE && set_mute.stream_id == 0) {
			retval = -EPERM;
			break;
		}
		retval = sst_set_mute(&set_mute);
		break;
	}
	case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): {
		struct snd_sst_get_stream_params get_params;

		pr_debug("IOCTL_GET_PARAMS received!\n");
		if (minor != 0) {
			retval = -EBADRQC;
			break;
		}

		retval = sst_get_stream_params(str_id, &get_params);
		if (retval) {
			retval = -EIO;
			break;
		}
		if (copy_to_user((struct snd_sst_get_stream_params __user *)arg,
					&get_params, sizeof(get_params))) {
			retval = -EFAULT;
			break;
		}
		sst_print_stream_params(&get_params);
		break;
	}

	case _IOC_NR(SNDRV_SST_MMAP_PLAY):
	case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): {
		struct snd_sst_mmap_buffs mmap_buf;

		pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n");
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		if (copy_from_user(&mmap_buf, (void __user *)arg,
				sizeof(mmap_buf))) {
			retval = -EFAULT;
			break;
		}
		retval = intel_sst_mmap_play_capture(str_id, &mmap_buf);
		break;
	}
	case _IOC_NR(SNDRV_SST_STREAM_DROP):
		pr_debug("SNDRV_SST_IOCTL_DROP received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EINVAL;
			break;
		}
		retval = sst_drop_stream(str_id);
		break;

	case _IOC_NR(SNDRV_SST_STREAM_GET_TSTAMP): {
		struct snd_sst_tstamp tstamp = {0};
		unsigned long long time, freq, mod;

		pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		memcpy_fromio(&tstamp,
			sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
			sizeof(tstamp));
		time = tstamp.samples_rendered;
		freq = (unsigned long long) tstamp.sampling_frequency;
		time = time * 1000; /* converting it to ms */
		mod = do_div(time, freq);
		if (copy_to_user((void __user *)arg, &time,
				sizeof(unsigned long long)))
			retval = -EFAULT;
		break;
	}

	case _IOC_NR(SNDRV_SST_STREAM_START):{
		struct stream_info *stream;

		pr_debug("SNDRV_SST_STREAM_START received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EINVAL;
			break;
		}
		retval = sst_validate_strid(str_id);
		if (retval)
			break;
		stream = &sst_drv_ctx->streams[str_id];
		mutex_lock(&stream->lock);
		if (stream->status == STREAM_INIT &&
			stream->need_draining != true) {
			stream->prev = stream->status;
			stream->status = STREAM_RUNNING;
			if (stream->ops == STREAM_OPS_PLAYBACK ||
				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
				retval = sst_play_frame(str_id);
			} else if (stream->ops == STREAM_OPS_CAPTURE)
				retval = sst_capture_frame(str_id);
			else {
				retval = -EINVAL;
				mutex_unlock(&stream->lock);
				break;
			}
			if (retval < 0) {
				stream->status = STREAM_INIT;
				mutex_unlock(&stream->lock);
				break;
			}
		} else {
			retval = -EINVAL;
		}
		mutex_unlock(&stream->lock);
		break;
	}

	case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): {
		struct snd_sst_target_device target_device;

		pr_debug("SET_TARGET_DEVICE recieved!\n");
		if (copy_from_user(&target_device, (void __user *)arg,
				sizeof(target_device))) {
			retval = -EFAULT;
			break;
		}
		if (minor != AM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		retval = sst_target_device_select(&target_device);
		break;
	}

	case _IOC_NR(SNDRV_SST_DRIVER_INFO): {
		struct snd_sst_driver_info info;

		pr_debug("SNDRV_SST_DRIVER_INFO recived\n");
		info.version = SST_VERSION_NUM;
		/* hard coding, shud get sumhow later */
		info.active_pcm_streams = sst_drv_ctx->stream_cnt -
						sst_drv_ctx->encoded_cnt;
		info.active_enc_streams = sst_drv_ctx->encoded_cnt;
		info.max_pcm_streams = MAX_ACTIVE_STREAM - MAX_ENC_STREAM;
		info.max_enc_streams = MAX_ENC_STREAM;
		info.buf_per_stream = sst_drv_ctx->mmap_len;
		if (copy_to_user((void __user *)arg, &info,
				sizeof(info)))
			retval = -EFAULT;
		break;
	}

	case _IOC_NR(SNDRV_SST_STREAM_DECODE): {
		struct snd_sst_dbufs param;
		struct snd_sst_dbufs dbufs_local;
		struct snd_sst_buffs ibufs, obufs;
		struct snd_sst_buff_entry *ibuf_tmp, *obuf_tmp;
		char __user *dest;

		pr_debug("SNDRV_SST_STREAM_DECODE received\n");
		if (minor != STREAM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		if (copy_from_user(&param, (void __user *)arg,
				sizeof(param))) {
			retval = -EFAULT;
			break;
		}

		dbufs_local.input_bytes_consumed = param.input_bytes_consumed;
		dbufs_local.output_bytes_produced =
					param.output_bytes_produced;

		if (copy_from_user(&ibufs, (void __user *)param.ibufs, sizeof(ibufs))) {
			retval = -EFAULT;
			break;
		}
		if (copy_from_user(&obufs, (void __user *)param.obufs, sizeof(obufs))) {
			retval = -EFAULT;
			break;
		}

		ibuf_tmp = kcalloc(ibufs.entries, sizeof(*ibuf_tmp), GFP_KERNEL);
		obuf_tmp = kcalloc(obufs.entries, sizeof(*obuf_tmp), GFP_KERNEL);
		if (!ibuf_tmp || !obuf_tmp) {
			retval = -ENOMEM;
			goto free_iobufs;
		}

		if (copy_from_user(ibuf_tmp, (void __user *)ibufs.buff_entry,
				ibufs.entries * sizeof(*ibuf_tmp))) {
			retval = -EFAULT;
			goto free_iobufs;
		}
		ibufs.buff_entry = ibuf_tmp;
		dbufs_local.ibufs = &ibufs;

		if (copy_from_user(obuf_tmp, (void __user *)obufs.buff_entry,
				obufs.entries * sizeof(*obuf_tmp))) {
			retval = -EFAULT;
			goto free_iobufs;
		}
		obufs.buff_entry = obuf_tmp;
		dbufs_local.obufs = &obufs;

		retval = sst_decode(str_id, &dbufs_local);
		if (retval) {
			retval = -EAGAIN;
			goto free_iobufs;
		}

		dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
		if (copy_to_user(dest,
				&dbufs_local.input_bytes_consumed,
				sizeof(unsigned long long))) {
			retval = -EFAULT;
			goto free_iobufs;
		}

		dest = (char __user *)arg + offsetof(struct snd_sst_dbufs, input_bytes_consumed);
		if (copy_to_user(dest,
				&dbufs_local.output_bytes_produced,
				sizeof(unsigned long long))) {
			retval = -EFAULT;
			goto free_iobufs;
		}
free_iobufs:
		kfree(ibuf_tmp);
		kfree(obuf_tmp);
		break;
	}

	case _IOC_NR(SNDRV_SST_STREAM_DRAIN):
		pr_debug("SNDRV_SST_STREAM_DRAIN received\n");
		if (minor != STREAM_MODULE) {
			retval = -EINVAL;
			break;
		}
		retval = sst_drain_stream(str_id);
		break;

	case _IOC_NR(SNDRV_SST_STREAM_BYTES_DECODED): {
		unsigned long long __user *bytes = (unsigned long long __user *)arg;
		struct snd_sst_tstamp tstamp = {0};

		pr_debug("STREAM_BYTES_DECODED received!\n");
		if (minor != STREAM_MODULE) {
			retval = -EINVAL;
			break;
		}
		memcpy_fromio(&tstamp,
			sst_drv_ctx->mailbox + SST_TIME_STAMP + str_id * sizeof(tstamp),
			sizeof(tstamp));
		if (copy_to_user(bytes, &tstamp.bytes_processed,
				sizeof(*bytes)))
			retval = -EFAULT;
		break;
	}
	case _IOC_NR(SNDRV_SST_FW_INFO): {
		struct snd_sst_fw_info *fw_info;

		pr_debug("SNDRV_SST_FW_INFO received\n");

		fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC);
		if (!fw_info) {
			retval = -ENOMEM;
			break;
		}
		retval = sst_get_fw_info(fw_info);
		if (retval) {
			retval = -EIO;
			kfree(fw_info);
			break;
		}
		if (copy_to_user((struct snd_sst_dbufs __user *)arg,
				fw_info, sizeof(*fw_info))) {
			kfree(fw_info);
			retval = -EFAULT;
			break;
		}
		/*sst_print_fw_info(fw_info);*/
		kfree(fw_info);
		break;
	}
	case _IOC_NR(SNDRV_SST_GET_ALGO):
	case _IOC_NR(SNDRV_SST_SET_ALGO):
		if (minor != AM_MODULE) {
			retval = -EBADRQC;
			break;
		}
		retval = intel_sst_ioctl_dsp(cmd, arg);
		break;
	default:
		retval = -EINVAL;
	}
	pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval);
	return retval;
}

