/*
 *  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 boundary  */
	/*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 - receives 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 received 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 received 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 received 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 received!\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 received!\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 received\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;
}

