/***************************************************************************
 * Copyright (c) 2005-2009, Broadcom Corporation.
 *
 *  Name: crystalhd_cmds . c
 *
 *  Description:
 *		BCM70010 Linux driver user command interfaces.
 *
 *  HISTORY:
 *
 **********************************************************************
 * This file is part of the crystalhd device driver.
 *
 * This driver 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 driver 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 driver.  If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/

#include "crystalhd.h"

static struct crystalhd_user *bc_cproc_get_uid(struct crystalhd_cmd *ctx)
{
	struct crystalhd_user *user = NULL;
	int i;

	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
		if (!ctx->user[i].in_use) {
			user = &ctx->user[i];
			break;
		}
	}

	return user;
}

static int bc_cproc_get_user_count(struct crystalhd_cmd *ctx)
{
	int i, count = 0;

	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
		if (ctx->user[i].in_use)
			count++;
	}

	return count;
}

static void bc_cproc_mark_pwr_state(struct crystalhd_cmd *ctx)
{
	int i;

	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
		if (!ctx->user[i].in_use)
			continue;
		if (ctx->user[i].mode == DTS_DIAG_MODE ||
		    ctx->user[i].mode == DTS_PLAYBACK_MODE) {
			ctx->pwr_state_change = 1;
			break;
		}
	}
}

static enum BC_STATUS bc_cproc_notify_mode(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	int rc = 0, i = 0;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	if (ctx->user[idata->u_id].mode != DTS_MODE_INV) {
		BCMLOG_ERR("Close the handle first..\n");
		return BC_STS_ERR_USAGE;
	}
	if (idata->udata.u.NotifyMode.Mode == DTS_MONITOR_MODE) {
		ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
		return BC_STS_SUCCESS;
	}
	if (ctx->state != BC_LINK_INVALID) {
		BCMLOG_ERR("Link invalid state %d\n", ctx->state);
		return BC_STS_ERR_USAGE;
	}
	/* Check for duplicate playback sessions..*/
	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
		if (ctx->user[i].mode == DTS_DIAG_MODE ||
		    ctx->user[i].mode == DTS_PLAYBACK_MODE) {
			BCMLOG_ERR("multiple playback sessions are not "
				   "supported..\n");
			return BC_STS_ERR_USAGE;
		}
	}
	ctx->cin_wait_exit = 0;
	ctx->user[idata->u_id].mode = idata->udata.u.NotifyMode.Mode;
	/* Setup mmap pool for uaddr sgl mapping..*/
	rc = crystalhd_create_dio_pool(ctx->adp, BC_LINK_MAX_SGLS);
	if (rc)
		return BC_STS_ERROR;

	/* Setup Hardware DMA rings */
	return crystalhd_hw_setup_dma_rings(&ctx->hw_ctx);
}

static enum BC_STATUS bc_cproc_get_version(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}
	idata->udata.u.VerInfo.DriverMajor = crystalhd_kmod_major;
	idata->udata.u.VerInfo.DriverMinor = crystalhd_kmod_minor;
	idata->udata.u.VerInfo.DriverRevision	= crystalhd_kmod_rev;
	return BC_STS_SUCCESS;
}


static enum BC_STATUS bc_cproc_get_hwtype(struct crystalhd_cmd *ctx,
					struct crystalhd_ioctl_data *idata)
{
	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	crystalhd_pci_cfg_rd(ctx->adp, 0, 2,
			   (uint32_t *)&idata->udata.u.hwType.PciVenId);
	crystalhd_pci_cfg_rd(ctx->adp, 2, 2,
			   (uint32_t *)&idata->udata.u.hwType.PciDevId);
	crystalhd_pci_cfg_rd(ctx->adp, 8, 1,
			   (uint32_t *)&idata->udata.u.hwType.HwRev);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_reg_rd(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	if (!ctx || !idata)
		return BC_STS_INV_ARG;
	idata->udata.u.regAcc.Value = bc_dec_reg_rd(ctx->adp,
					idata->udata.u.regAcc.Offset);
	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_reg_wr(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	if (!ctx || !idata)
		return BC_STS_INV_ARG;

	bc_dec_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
		      idata->udata.u.regAcc.Value);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_link_reg_rd(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	if (!ctx || !idata)
		return BC_STS_INV_ARG;

	idata->udata.u.regAcc.Value = crystalhd_reg_rd(ctx->adp,
					idata->udata.u.regAcc.Offset);
	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_link_reg_wr(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	if (!ctx || !idata)
		return BC_STS_INV_ARG;

	crystalhd_reg_wr(ctx->adp, idata->udata.u.regAcc.Offset,
		       idata->udata.u.regAcc.Value);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_mem_rd(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata || !idata->add_cdata)
		return BC_STS_INV_ARG;

	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
		BCMLOG_ERR("insufficient buffer\n");
		return BC_STS_INV_ARG;
	}
	sts = crystalhd_mem_rd(ctx->adp, idata->udata.u.devMem.StartOff,
			     idata->udata.u.devMem.NumDwords,
			     (uint32_t *)idata->add_cdata);
	return sts;

}

static enum BC_STATUS bc_cproc_mem_wr(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata || !idata->add_cdata)
		return BC_STS_INV_ARG;

	if (idata->udata.u.devMem.NumDwords > (idata->add_cdata_sz / 4)) {
		BCMLOG_ERR("insufficient buffer\n");
		return BC_STS_INV_ARG;
	}

	sts = crystalhd_mem_wr(ctx->adp, idata->udata.u.devMem.StartOff,
			     idata->udata.u.devMem.NumDwords,
			     (uint32_t *)idata->add_cdata);
	return sts;
}

static enum BC_STATUS bc_cproc_cfg_rd(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	uint32_t ix, cnt, off, len;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	uint32_t *temp;

	if (!ctx || !idata)
		return BC_STS_INV_ARG;

	temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
	off = idata->udata.u.pciCfg.Offset;
	len = idata->udata.u.pciCfg.Size;

	if (len <= 4)
		return crystalhd_pci_cfg_rd(ctx->adp, off, len, temp);

	/* Truncate to dword alignment..*/
	len = 4;
	cnt = idata->udata.u.pciCfg.Size / len;
	for (ix = 0; ix < cnt; ix++) {
		sts = crystalhd_pci_cfg_rd(ctx->adp, off, len, &temp[ix]);
		if (sts != BC_STS_SUCCESS) {
			BCMLOG_ERR("config read : %d\n", sts);
			return sts;
		}
		off += len;
	}

	return sts;
}

static enum BC_STATUS bc_cproc_cfg_wr(struct crystalhd_cmd *ctx,
				 struct crystalhd_ioctl_data *idata)
{
	uint32_t ix, cnt, off, len;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	uint32_t *temp;

	if (!ctx || !idata)
		return BC_STS_INV_ARG;

	temp = (uint32_t *) idata->udata.u.pciCfg.pci_cfg_space;
	off = idata->udata.u.pciCfg.Offset;
	len = idata->udata.u.pciCfg.Size;

	if (len <= 4)
		return crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[0]);

	/* Truncate to dword alignment..*/
	len = 4;
	cnt = idata->udata.u.pciCfg.Size / len;
	for (ix = 0; ix < cnt; ix++) {
		sts = crystalhd_pci_cfg_wr(ctx->adp, off, len, temp[ix]);
		if (sts != BC_STS_SUCCESS) {
			BCMLOG_ERR("config write : %d\n", sts);
			return sts;
		}
		off += len;
	}

	return sts;
}

static enum BC_STATUS bc_cproc_download_fw(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata || !idata->add_cdata || !idata->add_cdata_sz) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	if (ctx->state != BC_LINK_INVALID) {
		BCMLOG_ERR("Link invalid state %d\n", ctx->state);
		return BC_STS_ERR_USAGE;
	}

	sts = crystalhd_download_fw(ctx->adp, (uint8_t *)idata->add_cdata,
				  idata->add_cdata_sz);

	if (sts != BC_STS_SUCCESS) {
		BCMLOG_ERR("Firmware Download Failure!! - %d\n", sts);
	} else
		ctx->state |= BC_LINK_INIT;

	return sts;
}

/*
 * We use the FW_CMD interface to sync up playback state with application
 * and  firmware. This function will perform the required pre and post
 * processing of the Firmware commands.
 *
 * Pause -
 *	Disable capture after decoder pause.
 * Resume -
 *	First enable capture and issue decoder resume command.
 * Flush -
 *	Abort pending input transfers and issue decoder flush command.
 *
 */
static enum BC_STATUS bc_cproc_do_fw_cmd(struct crystalhd_cmd *ctx,
					struct crystalhd_ioctl_data *idata)
{
	enum BC_STATUS sts;
	uint32_t *cmd;

	if (!(ctx->state & BC_LINK_INIT)) {
		BCMLOG_ERR("Link invalid state %d\n", ctx->state);
		return BC_STS_ERR_USAGE;
	}

	cmd = idata->udata.u.fwCmd.cmd;

	/* Pre-Process */
	if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
		if (!cmd[3]) {
			ctx->state &= ~BC_LINK_PAUSED;
			crystalhd_hw_unpause(&ctx->hw_ctx);
		}
	} else if (cmd[0] == eCMD_C011_DEC_CHAN_FLUSH) {
		BCMLOG(BCMLOG_INFO, "Flush issued\n");
		if (cmd[3])
			ctx->cin_wait_exit = 1;
	}

	sts = crystalhd_do_fw_cmd(&ctx->hw_ctx, &idata->udata.u.fwCmd);

	if (sts != BC_STS_SUCCESS) {
		BCMLOG(BCMLOG_INFO, "fw cmd %x failed\n", cmd[0]);
		return sts;
	}

	/* Post-Process */
	if (cmd[0] == eCMD_C011_DEC_CHAN_PAUSE) {
		if (cmd[3]) {
			ctx->state |= BC_LINK_PAUSED;
			crystalhd_hw_pause(&ctx->hw_ctx);
		}
	}

	return sts;
}

static void bc_proc_in_completion(struct crystalhd_dio_req *dio_hnd,
				  wait_queue_head_t *event, enum BC_STATUS sts)
{
	if (!dio_hnd || !event) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return;
	}
	if (sts == BC_STS_IO_USER_ABORT)
		return;

	dio_hnd->uinfo.comp_sts = sts;
	dio_hnd->uinfo.ev_sts = 1;
	crystalhd_set_event(event);
}

static enum BC_STATUS bc_cproc_codein_sleep(struct crystalhd_cmd *ctx)
{
	wait_queue_head_t sleep_ev;
	int rc = 0;

	if (ctx->state & BC_LINK_SUSPEND)
		return BC_STS_IO_USER_ABORT;

	if (ctx->cin_wait_exit) {
		ctx->cin_wait_exit = 0;
		return BC_STS_CMD_CANCELLED;
	}
	crystalhd_create_event(&sleep_ev);
	crystalhd_wait_on_event(&sleep_ev, 0, 100, rc, 0);
	if (rc == -EINTR)
		return BC_STS_IO_USER_ABORT;

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_hw_txdma(struct crystalhd_cmd *ctx,
				   struct crystalhd_ioctl_data *idata,
				   struct crystalhd_dio_req *dio)
{
	uint32_t tx_listid = 0;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	wait_queue_head_t event;
	int rc = 0;

	if (!ctx || !idata || !dio) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	crystalhd_create_event(&event);

	ctx->tx_list_id = 0;
	/* msleep_interruptible(2000); */
	sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio, bc_proc_in_completion,
				 &event, &tx_listid,
				 idata->udata.u.ProcInput.Encrypted);

	while (sts == BC_STS_BUSY) {
		sts = bc_cproc_codein_sleep(ctx);
		if (sts != BC_STS_SUCCESS)
			break;
		sts = crystalhd_hw_post_tx(&ctx->hw_ctx, dio,
					 bc_proc_in_completion,
					 &event, &tx_listid,
					 idata->udata.u.ProcInput.Encrypted);
	}
	if (sts != BC_STS_SUCCESS) {
		BCMLOG(BCMLOG_DBG, "_hw_txdma returning sts:%d\n", sts);
		return sts;
	}
	if (ctx->cin_wait_exit)
		ctx->cin_wait_exit = 0;

	ctx->tx_list_id = tx_listid;

	/* _post() succeeded.. wait for the completion. */
	crystalhd_wait_on_event(&event, (dio->uinfo.ev_sts), 3000, rc, 0);
	ctx->tx_list_id = 0;
	if (!rc) {
		return dio->uinfo.comp_sts;
	} else if (rc == -EBUSY) {
		BCMLOG(BCMLOG_DBG, "_tx_post() T/O\n");
		sts = BC_STS_TIMEOUT;
	} else if (rc == -EINTR) {
		BCMLOG(BCMLOG_DBG, "Tx Wait Signal int.\n");
		sts = BC_STS_IO_USER_ABORT;
	} else {
		sts = BC_STS_IO_ERROR;
	}

	/* We are cancelling the IO from the same context as the _post().
	 * so no need to wait on the event again.. the return itself
	 * ensures the release of our resources.
	 */
	crystalhd_hw_cancel_tx(&ctx->hw_ctx, tx_listid);

	return sts;
}

/* Helper function to check on user buffers */
static enum BC_STATUS bc_cproc_check_inbuffs(bool pin, void *ubuff, uint32_t ub_sz,
					uint32_t uv_off, bool en_422)
{
	if (!ubuff || !ub_sz) {
		BCMLOG_ERR("%s->Invalid Arg %p %x\n",
			((pin) ? "TX" : "RX"), ubuff, ub_sz);
		return BC_STS_INV_ARG;
	}

	/* Check for alignment */
	if (((uintptr_t)ubuff) & 0x03) {
		BCMLOG_ERR("%s-->Un-aligned address not implemented yet.. %p\n",
				((pin) ? "TX" : "RX"), ubuff);
		return BC_STS_NOT_IMPL;
	}
	if (pin)
		return BC_STS_SUCCESS;

	if (!en_422 && !uv_off) {
		BCMLOG_ERR("Need UV offset for 420 mode.\n");
		return BC_STS_INV_ARG;
	}

	if (en_422 && uv_off) {
		BCMLOG_ERR("UV offset in 422 mode ??\n");
		return BC_STS_INV_ARG;
	}

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_proc_input(struct crystalhd_cmd *ctx,
					struct crystalhd_ioctl_data *idata)
{
	void *ubuff;
	uint32_t ub_sz;
	struct crystalhd_dio_req *dio_hnd = NULL;
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	ubuff = idata->udata.u.ProcInput.pDmaBuff;
	ub_sz = idata->udata.u.ProcInput.BuffSz;

	sts = bc_cproc_check_inbuffs(1, ubuff, ub_sz, 0, 0);
	if (sts != BC_STS_SUCCESS)
		return sts;

	sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, 0, 0, 1, &dio_hnd);
	if (sts != BC_STS_SUCCESS) {
		BCMLOG_ERR("dio map - %d\n", sts);
		return sts;
	}

	if (!dio_hnd)
		return BC_STS_ERROR;

	sts = bc_cproc_hw_txdma(ctx, idata, dio_hnd);

	crystalhd_unmap_dio(ctx->adp, dio_hnd);

	return sts;
}

static enum BC_STATUS bc_cproc_add_cap_buff(struct crystalhd_cmd *ctx,
				       struct crystalhd_ioctl_data *idata)
{
	void *ubuff;
	uint32_t ub_sz, uv_off;
	bool en_422;
	struct crystalhd_dio_req *dio_hnd = NULL;
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	ubuff = idata->udata.u.RxBuffs.YuvBuff;
	ub_sz = idata->udata.u.RxBuffs.YuvBuffSz;
	uv_off = idata->udata.u.RxBuffs.UVbuffOffset;
	en_422 = idata->udata.u.RxBuffs.b422Mode;

	sts = bc_cproc_check_inbuffs(0, ubuff, ub_sz, uv_off, en_422);
	if (sts != BC_STS_SUCCESS)
		return sts;

	sts = crystalhd_map_dio(ctx->adp, ubuff, ub_sz, uv_off,
			      en_422, 0, &dio_hnd);
	if (sts != BC_STS_SUCCESS) {
		BCMLOG_ERR("dio map - %d\n", sts);
		return sts;
	}

	if (!dio_hnd)
		return BC_STS_ERROR;

	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio_hnd, (ctx->state == BC_LINK_READY));
	if ((sts != BC_STS_SUCCESS) && (sts != BC_STS_BUSY)) {
		crystalhd_unmap_dio(ctx->adp, dio_hnd);
		return sts;
	}

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_fmt_change(struct crystalhd_cmd *ctx,
				     struct crystalhd_dio_req *dio)
{
	enum BC_STATUS sts = BC_STS_SUCCESS;

	sts = crystalhd_hw_add_cap_buffer(&ctx->hw_ctx, dio, 0);
	if (sts != BC_STS_SUCCESS)
		return sts;

	ctx->state |= BC_LINK_FMT_CHG;
	if (ctx->state == BC_LINK_READY)
		sts = crystalhd_hw_start_capture(&ctx->hw_ctx);

	return sts;
}

static enum BC_STATUS bc_cproc_fetch_frame(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	struct crystalhd_dio_req *dio = NULL;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	struct BC_DEC_OUT_BUFF *frame;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	if (!(ctx->state & BC_LINK_CAP_EN)) {
		BCMLOG(BCMLOG_DBG, "Capture not enabled..%x\n", ctx->state);
		return BC_STS_ERR_USAGE;
	}

	frame = &idata->udata.u.DecOutData;

	sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
	if (sts != BC_STS_SUCCESS)
		return (ctx->state & BC_LINK_SUSPEND) ? BC_STS_IO_USER_ABORT : sts;

	frame->Flags = dio->uinfo.comp_flags;

	if (frame->Flags & COMP_FLAG_FMT_CHANGE)
		return bc_cproc_fmt_change(ctx, dio);

	frame->OutPutBuffs.YuvBuff = dio->uinfo.xfr_buff;
	frame->OutPutBuffs.YuvBuffSz = dio->uinfo.xfr_len;
	frame->OutPutBuffs.UVbuffOffset = dio->uinfo.uv_offset;
	frame->OutPutBuffs.b422Mode = dio->uinfo.b422mode;

	frame->OutPutBuffs.YBuffDoneSz = dio->uinfo.y_done_sz;
	frame->OutPutBuffs.UVBuffDoneSz = dio->uinfo.uv_done_sz;

	crystalhd_unmap_dio(ctx->adp, dio);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_start_capture(struct crystalhd_cmd *ctx,
					struct crystalhd_ioctl_data *idata)
{
	ctx->state |= BC_LINK_CAP_EN;
	if (ctx->state == BC_LINK_READY)
		return crystalhd_hw_start_capture(&ctx->hw_ctx);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_flush_cap_buffs(struct crystalhd_cmd *ctx,
					  struct crystalhd_ioctl_data *idata)
{
	struct crystalhd_dio_req *dio = NULL;
	enum BC_STATUS sts = BC_STS_SUCCESS;
	struct BC_DEC_OUT_BUFF *frame;
	uint32_t count;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	if (!(ctx->state & BC_LINK_CAP_EN))
		return BC_STS_ERR_USAGE;

	/* We should ack flush even when we are in paused/suspend state */
	if (!(ctx->state & BC_LINK_READY))
		return crystalhd_hw_stop_capture(&ctx->hw_ctx);

	ctx->state &= ~(BC_LINK_CAP_EN|BC_LINK_FMT_CHG);

	frame = &idata->udata.u.DecOutData;
	for (count = 0; count < BC_RX_LIST_CNT; count++) {

		sts = crystalhd_hw_get_cap_buffer(&ctx->hw_ctx, &frame->PibInfo, &dio);
		if (sts != BC_STS_SUCCESS)
			break;

		crystalhd_unmap_dio(ctx->adp, dio);
	}

	return crystalhd_hw_stop_capture(&ctx->hw_ctx);
}

static enum BC_STATUS bc_cproc_get_stats(struct crystalhd_cmd *ctx,
				    struct crystalhd_ioctl_data *idata)
{
	struct BC_DTS_STATS *stats;
	struct crystalhd_hw_stats	hw_stats;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	crystalhd_hw_stats(&ctx->hw_ctx, &hw_stats);

	stats = &idata->udata.u.drvStat;
	stats->drvRLL = hw_stats.rdyq_count;
	stats->drvFLL = hw_stats.freeq_count;
	stats->DrvTotalFrmDropped = hw_stats.rx_errors;
	stats->DrvTotalHWErrs = hw_stats.rx_errors + hw_stats.tx_errors;
	stats->intCount = hw_stats.num_interrupts;
	stats->DrvIgnIntrCnt = hw_stats.num_interrupts -
				hw_stats.dev_interrupts;
	stats->TxFifoBsyCnt = hw_stats.cin_busy;
	stats->pauseCount = hw_stats.pause_cnt;

	if (ctx->pwr_state_change)
		stats->pwr_state_change = 1;
	if (ctx->state & BC_LINK_PAUSED)
		stats->DrvPauseTime = 1;

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_reset_stats(struct crystalhd_cmd *ctx,
				      struct crystalhd_ioctl_data *idata)
{
	crystalhd_hw_stats(&ctx->hw_ctx, NULL);

	return BC_STS_SUCCESS;
}

static enum BC_STATUS bc_cproc_chg_clk(struct crystalhd_cmd *ctx,
				  struct crystalhd_ioctl_data *idata)
{
	struct BC_CLOCK *clock;
	uint32_t oldClk;
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Arg!!\n");
		return BC_STS_INV_ARG;
	}

	clock = &idata->udata.u.clockValue;
	oldClk = ctx->hw_ctx.core_clock_mhz;
	ctx->hw_ctx.core_clock_mhz = clock->clk;

	if (ctx->state & BC_LINK_READY) {
		sts = crystalhd_hw_set_core_clock(&ctx->hw_ctx);
		if (sts == BC_STS_CLK_NOCHG)
			ctx->hw_ctx.core_clock_mhz = oldClk;
	}

	clock->clk = ctx->hw_ctx.core_clock_mhz;

	return sts;
}

/*=============== Cmd Proc Table.. ======================================*/
static const struct crystalhd_cmd_tbl	g_crystalhd_cproc_tbl[] = {
	{ BCM_IOC_GET_VERSION,		bc_cproc_get_version,	0},
	{ BCM_IOC_GET_HWTYPE,		bc_cproc_get_hwtype,	0},
	{ BCM_IOC_REG_RD,		bc_cproc_reg_rd,	0},
	{ BCM_IOC_REG_WR,		bc_cproc_reg_wr,	0},
	{ BCM_IOC_FPGA_RD,		bc_cproc_link_reg_rd,	0},
	{ BCM_IOC_FPGA_WR,		bc_cproc_link_reg_wr,	0},
	{ BCM_IOC_MEM_RD,		bc_cproc_mem_rd,	0},
	{ BCM_IOC_MEM_WR,		bc_cproc_mem_wr,	0},
	{ BCM_IOC_RD_PCI_CFG,		bc_cproc_cfg_rd,	0},
	{ BCM_IOC_WR_PCI_CFG,		bc_cproc_cfg_wr,	1},
	{ BCM_IOC_FW_DOWNLOAD,		bc_cproc_download_fw,	1},
	{ BCM_IOC_FW_CMD,		bc_cproc_do_fw_cmd,	1},
	{ BCM_IOC_PROC_INPUT,		bc_cproc_proc_input,	1},
	{ BCM_IOC_ADD_RXBUFFS,		bc_cproc_add_cap_buff,	1},
	{ BCM_IOC_FETCH_RXBUFF,		bc_cproc_fetch_frame,	1},
	{ BCM_IOC_START_RX_CAP,		bc_cproc_start_capture,	1},
	{ BCM_IOC_FLUSH_RX_CAP,		bc_cproc_flush_cap_buffs, 1},
	{ BCM_IOC_GET_DRV_STAT,		bc_cproc_get_stats,	0},
	{ BCM_IOC_RST_DRV_STAT,		bc_cproc_reset_stats,	0},
	{ BCM_IOC_NOTIFY_MODE,		bc_cproc_notify_mode,	0},
	{ BCM_IOC_CHG_CLK,		bc_cproc_chg_clk, 0},
	{ BCM_IOC_END,			NULL},
};

/*=============== Cmd Proc Functions.. ===================================*/

/**
 * crystalhd_suspend - Power management suspend request.
 * @ctx: Command layer context.
 * @idata: Iodata - required for internal use.
 *
 * Return:
 *	status
 *
 * 1. Set the state to Suspend.
 * 2. Flush the Rx Buffers it will unmap all the buffers and
 *    stop the RxDMA engine.
 * 3. Cancel The TX Io and Stop Dma Engine.
 * 4. Put the DDR in to deep sleep.
 * 5. Stop the hardware putting it in to Reset State.
 *
 * Current gstreamer frame work does not provide any power management
 * related notification to user mode decoder plug-in. As a work-around
 * we pass on the power mangement notification to our plug-in by completing
 * all outstanding requests with BC_STS_IO_USER_ABORT return code.
 */
enum BC_STATUS crystalhd_suspend(struct crystalhd_cmd *ctx,
				struct crystalhd_ioctl_data *idata)
{
	enum BC_STATUS sts = BC_STS_SUCCESS;

	if (!ctx || !idata) {
		BCMLOG_ERR("Invalid Parameters\n");
		return BC_STS_ERROR;
	}

	if (ctx->state & BC_LINK_SUSPEND)
		return BC_STS_SUCCESS;

	if (ctx->state == BC_LINK_INVALID) {
		BCMLOG(BCMLOG_DBG, "Nothing To Do Suspend Success\n");
		return BC_STS_SUCCESS;
	}

	ctx->state |= BC_LINK_SUSPEND;

	bc_cproc_mark_pwr_state(ctx);

	if (ctx->state & BC_LINK_CAP_EN) {
		sts = bc_cproc_flush_cap_buffs(ctx, idata);
		if (sts != BC_STS_SUCCESS)
			return sts;
	}

	if (ctx->tx_list_id) {
		sts = crystalhd_hw_cancel_tx(&ctx->hw_ctx, ctx->tx_list_id);
		if (sts != BC_STS_SUCCESS)
			return sts;
	}

	sts = crystalhd_hw_suspend(&ctx->hw_ctx);
	if (sts != BC_STS_SUCCESS)
		return sts;

	BCMLOG(BCMLOG_DBG, "BCM70012 suspend success\n");

	return BC_STS_SUCCESS;
}

/**
 * crystalhd_resume - Resume frame capture.
 * @ctx: Command layer contextx.
 *
 * Return:
 *	status
 *
 *
 * Resume frame capture.
 *
 * PM_Resume can't resume the playback state back to pre-suspend state
 * because we don't keep video clip related information within driver.
 * To get back to the pre-suspend state App will re-open the device and
 * start a new playback session from the pre-suspend clip position.
 *
 */
enum BC_STATUS crystalhd_resume(struct crystalhd_cmd *ctx)
{
	BCMLOG(BCMLOG_DBG, "crystalhd_resume Success %x\n", ctx->state);

	bc_cproc_mark_pwr_state(ctx);

	return BC_STS_SUCCESS;
}

/**
 * crystalhd_user_open - Create application handle.
 * @ctx: Command layer contextx.
 * @user_ctx: User ID context.
 *
 * Return:
 *	status
 *
 * Creates an application specific UID and allocates
 * application specific resources. HW layer initialization
 * is done for the first open request.
 */
enum BC_STATUS crystalhd_user_open(struct crystalhd_cmd *ctx,
			    struct crystalhd_user **user_ctx)
{
	struct crystalhd_user *uc;

	if (!ctx || !user_ctx) {
		BCMLOG_ERR("Invalid arg..\n");
		return BC_STS_INV_ARG;
	}

	uc = bc_cproc_get_uid(ctx);
	if (!uc) {
		BCMLOG(BCMLOG_INFO, "No free user context...\n");
		return BC_STS_BUSY;
	}

	BCMLOG(BCMLOG_INFO, "Opening new user[%x] handle\n", uc->uid);

	crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);

	uc->in_use = 1;

	*user_ctx = uc;

	return BC_STS_SUCCESS;
}

/**
 * crystalhd_user_close - Close application handle.
 * @ctx: Command layer contextx.
 * @uc: User ID context.
 *
 * Return:
 *	status
 *
 * Closer application handle and release app specific
 * resources.
 */
enum BC_STATUS crystalhd_user_close(struct crystalhd_cmd *ctx, struct crystalhd_user *uc)
{
	uint32_t mode = uc->mode;

	ctx->user[uc->uid].mode = DTS_MODE_INV;
	ctx->user[uc->uid].in_use = 0;
	ctx->cin_wait_exit = 1;
	ctx->pwr_state_change = 0;

	BCMLOG(BCMLOG_INFO, "Closing user[%x] handle\n", uc->uid);

	if ((mode == DTS_DIAG_MODE) || (mode == DTS_PLAYBACK_MODE)) {
		crystalhd_hw_free_dma_rings(&ctx->hw_ctx);
		crystalhd_destroy_dio_pool(ctx->adp);
	} else if (bc_cproc_get_user_count(ctx)) {
		return BC_STS_SUCCESS;
	}

	crystalhd_hw_close(&ctx->hw_ctx);

	ctx->state = BC_LINK_INVALID;

	return BC_STS_SUCCESS;
}

/**
 * crystalhd_setup_cmd_context - Setup Command layer resources.
 * @ctx: Command layer contextx.
 * @adp: Adapter context
 *
 * Return:
 *	status
 *
 * Called at the time of driver load.
 */
enum BC_STATUS __devinit crystalhd_setup_cmd_context(struct crystalhd_cmd *ctx,
				    struct crystalhd_adp *adp)
{
	int i = 0;

	if (!ctx || !adp) {
		BCMLOG_ERR("Invalid arg!!\n");
		return BC_STS_INV_ARG;
	}

	if (ctx->adp)
		BCMLOG(BCMLOG_DBG, "Resetting Cmd context delete missing..\n");

	ctx->adp = adp;
	for (i = 0; i < BC_LINK_MAX_OPENS; i++) {
		ctx->user[i].uid = i;
		ctx->user[i].in_use = 0;
		ctx->user[i].mode = DTS_MODE_INV;
	}

	/*Open and Close the Hardware to put it in to sleep state*/
	crystalhd_hw_open(&ctx->hw_ctx, ctx->adp);
	crystalhd_hw_close(&ctx->hw_ctx);
	return BC_STS_SUCCESS;
}

/**
 * crystalhd_delete_cmd_context - Release Command layer resources.
 * @ctx: Command layer contextx.
 *
 * Return:
 *	status
 *
 * Called at the time of driver un-load.
 */
enum BC_STATUS __devexit crystalhd_delete_cmd_context(struct crystalhd_cmd *ctx)
{
	BCMLOG(BCMLOG_DBG, "Deleting Command context..\n");

	ctx->adp = NULL;

	return BC_STS_SUCCESS;
}

/**
 * crystalhd_get_cmd_proc  - Cproc table lookup.
 * @ctx: Command layer contextx.
 * @cmd: IOCTL command code.
 * @uc: User ID context.
 *
 * Return:
 *	command proc function pointer
 *
 * This function checks the process context, application's
 * mode of operation and returns the function pointer
 * from the cproc table.
 */
crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd,
				      struct crystalhd_user *uc)
{
	crystalhd_cmd_proc cproc = NULL;
	unsigned int i, tbl_sz;

	if (!ctx) {
		BCMLOG_ERR("Invalid arg.. Cmd[%d]\n", cmd);
		return NULL;
	}

	if ((cmd != BCM_IOC_GET_DRV_STAT) && (ctx->state & BC_LINK_SUSPEND)) {
		BCMLOG_ERR("Invalid State [suspend Set].. Cmd[%d]\n", cmd);
		return NULL;
	}

	tbl_sz = sizeof(g_crystalhd_cproc_tbl) / sizeof(struct crystalhd_cmd_tbl);
	for (i = 0; i < tbl_sz; i++) {
		if (g_crystalhd_cproc_tbl[i].cmd_id == cmd) {
			if ((uc->mode == DTS_MONITOR_MODE) &&
			    (g_crystalhd_cproc_tbl[i].block_mon)) {
				BCMLOG(BCMLOG_INFO, "Blocking cmd %d\n", cmd);
				break;
			}
			cproc = g_crystalhd_cproc_tbl[i].cmd_proc;
			break;
		}
	}

	return cproc;
}

/**
 * crystalhd_cmd_interrupt - ISR entry point
 * @ctx: Command layer contextx.
 *
 * Return:
 *	TRUE: If interrupt from bcm70012 device.
 *
 *
 * ISR entry point from OS layer.
 */
bool crystalhd_cmd_interrupt(struct crystalhd_cmd *ctx)
{
	if (!ctx) {
		BCMLOG_ERR("Invalid arg..\n");
		return 0;
	}

	return crystalhd_hw_interrupt(ctx->adp, &ctx->hw_ctx);
}
