/*
 *  Driver for the Conexant CX25821 PCIe bridge
 *
 *  Copyright (C) 2009 Conexant Systems Inc.
 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.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; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "cx25821.h"
#include "cx25821-medusa-video.h"
#include "cx25821-biffuncs.h"

/*
 * medusa_enable_bluefield_output()
 *
 * Enable the generation of blue filed output if no video
 *
 */
static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
					   int enable)
{
	int ret_val = 1;
	u32 value = 0;
	u32 tmp = 0;
	int out_ctrl = OUT_CTRL1;
	int out_ctrl_ns = OUT_CTRL_NS;

	switch (channel) {
	default:
	case VDEC_A:
		break;
	case VDEC_B:
		out_ctrl = VDEC_B_OUT_CTRL1;
		out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
		break;
	case VDEC_C:
		out_ctrl = VDEC_C_OUT_CTRL1;
		out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
		break;
	case VDEC_D:
		out_ctrl = VDEC_D_OUT_CTRL1;
		out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
		break;
	case VDEC_E:
		out_ctrl = VDEC_E_OUT_CTRL1;
		out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
		return;
	case VDEC_F:
		out_ctrl = VDEC_F_OUT_CTRL1;
		out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
		return;
	case VDEC_G:
		out_ctrl = VDEC_G_OUT_CTRL1;
		out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
		return;
	case VDEC_H:
		out_ctrl = VDEC_H_OUT_CTRL1;
		out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
		return;
	}

	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
	value &= 0xFFFFFF7F;	/* clear BLUE_FIELD_EN */
	if (enable)
		value |= 0x00000080;	/* set BLUE_FIELD_EN */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);

	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
	value &= 0xFFFFFF7F;
	if (enable)
		value |= 0x00000080;	/* set BLUE_FIELD_EN */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
}

static int medusa_initialize_ntsc(struct cx25821_dev *dev)
{
	int ret_val = 0;
	int i = 0;
	u32 value = 0;
	u32 tmp = 0;

	mutex_lock(&dev->lock);

	for (i = 0; i < MAX_DECODERS; i++) {
		/* set video format NTSC-M */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
				     &tmp);
		value &= 0xFFFFFFF0;
		/* enable the fast locking mode bit[16] */
		value |= 0x10001;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
				      value);

		/* resolution NTSC 720x480 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
		value &= 0x00C00C00;
		value |= 0x612D0074;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      HORIZ_TIM_CTRL + (0x200 * i), value);

		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     VERT_TIM_CTRL + (0x200 * i), &tmp);
		value &= 0x00C00C00;
		value |= 0x1C1E001A;	/* vblank_cnt + 2 to get camera ID */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      VERT_TIM_CTRL + (0x200 * i), value);

		/* chroma subcarrier step size */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      SC_STEP_SIZE + (0x200 * i), 0x43E00000);

		/* enable VIP optional active */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     OUT_CTRL_NS + (0x200 * i), &tmp);
		value &= 0xFFFBFFFF;
		value |= 0x00040000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      OUT_CTRL_NS + (0x200 * i), value);

		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
				     &tmp);
		value &= 0xFFFBFFFF;
		value |= 0x00040000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
				      value);

		/*
		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
		 * when the input switching rate < 16 fields
		*/
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     MISC_TIM_CTRL + (0x200 * i), &tmp);
		/* disable special play detection */
		value = setBitAtPos(value, 14);
		value = clearBitAtPos(value, 15);
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      MISC_TIM_CTRL + (0x200 * i), value);

		/* set vbi_gate_en to 0 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
				     &tmp);
		value = clearBitAtPos(value, 29);
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
				      value);

		/* Enable the generation of blue field output if no video */
		medusa_enable_bluefield_output(dev, i, 1);
	}

	for (i = 0; i < MAX_ENCODERS; i++) {
		/* NTSC hclock */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_1 + (0x100 * i), &tmp);
		value &= 0xF000FC00;
		value |= 0x06B402D0;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_1 + (0x100 * i), value);

		/* burst begin and burst end */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_2 + (0x100 * i), &tmp);
		value &= 0xFF000000;
		value |= 0x007E9054;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_2 + (0x100 * i), value);

		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_3 + (0x100 * i), &tmp);
		value &= 0xFC00FE00;
		value |= 0x00EC00F0;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_3 + (0x100 * i), value);

		/* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_4 + (0x100 * i), &tmp);
		value &= 0x00FCFFFF;
		value |= 0x13020000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_4 + (0x100 * i), value);

		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_5 + (0x100 * i), &tmp);
		value &= 0xFFFF0000;
		value |= 0x0000E575;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_5 + (0x100 * i), value);

		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_6 + (0x100 * i), 0x009A89C1);

		/* Subcarrier Increment */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
	}

	/* set picture resolutions */
	/* 0 - 720 */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
	/* 0 - 480 */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);

	/* set Bypass input format to NTSC 525 lines */
	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
	value |= 0x00080200;
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);

	mutex_unlock(&dev->lock);

	return ret_val;
}

static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
{
	int ret_val = -1;
	u32 value = 0, tmp = 0;

	/* Setup for 2D threshold */
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
			      0x20002861);
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
			      0x20002861);
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
			      0x200A1023);

	/* Setup flat chroma and luma thresholds */
	value =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
	value &= 0x06230000;
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);

	/* set comb 2D blend */
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
			      0x210F0F0F);

	/* COMB MISC CONTROL */
	ret_val =
	    cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
			      0x41120A7F);

	return ret_val;
}

static int medusa_initialize_pal(struct cx25821_dev *dev)
{
	int ret_val = 0;
	int i = 0;
	u32 value = 0;
	u32 tmp = 0;

	mutex_lock(&dev->lock);

	for (i = 0; i < MAX_DECODERS; i++) {
		/* set video format PAL-BDGHI */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
				     &tmp);
		value &= 0xFFFFFFF0;
		/* enable the fast locking mode bit[16] */
		value |= 0x10004;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
				      value);

		/* resolution PAL 720x576 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     HORIZ_TIM_CTRL + (0x200 * i), &tmp);
		value &= 0x00C00C00;
		value |= 0x632D007D;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      HORIZ_TIM_CTRL + (0x200 * i), value);

		/* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     VERT_TIM_CTRL + (0x200 * i), &tmp);
		value &= 0x00C00C00;
		value |= 0x28240026;	/* vblank_cnt + 2 to get camera ID */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      VERT_TIM_CTRL + (0x200 * i), value);

		/* chroma subcarrier step size */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);

		/* enable VIP optional active */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     OUT_CTRL_NS + (0x200 * i), &tmp);
		value &= 0xFFFBFFFF;
		value |= 0x00040000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      OUT_CTRL_NS + (0x200 * i), value);

		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
				     &tmp);
		value &= 0xFFFBFFFF;
		value |= 0x00040000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
				      value);

		/*
		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
		 * when the input switching rate < 16 fields
		 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     MISC_TIM_CTRL + (0x200 * i), &tmp);
		/* disable special play detection */
		value = setBitAtPos(value, 14);
		value = clearBitAtPos(value, 15);
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      MISC_TIM_CTRL + (0x200 * i), value);

		/* set vbi_gate_en to 0 */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
				     &tmp);
		value = clearBitAtPos(value, 29);
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
				      value);

		medusa_PALCombInit(dev, i);

		/* Enable the generation of blue field output if no video */
		medusa_enable_bluefield_output(dev, i, 1);
	}

	for (i = 0; i < MAX_ENCODERS; i++) {
		/* PAL hclock */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_1 + (0x100 * i), &tmp);
		value &= 0xF000FC00;
		value |= 0x06C002D0;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_1 + (0x100 * i), value);

		/* burst begin and burst end */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_2 + (0x100 * i), &tmp);
		value &= 0xFF000000;
		value |= 0x007E9754;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_2 + (0x100 * i), value);

		/* hblank and vactive */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_3 + (0x100 * i), &tmp);
		value &= 0xFC00FE00;
		value |= 0x00FC0120;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_3 + (0x100 * i), value);

		/* set PAL vblank, phase alternation, 0 IRE pedestal */
		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_4 + (0x100 * i), &tmp);
		value &= 0x00FCFFFF;
		value |= 0x14010000;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_4 + (0x100 * i), value);

		value =
		    cx25821_i2c_read(&dev->i2c_bus[0],
				     DENC_A_REG_5 + (0x100 * i), &tmp);
		value &= 0xFFFF0000;
		value |= 0x0000F078;
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_5 + (0x100 * i), value);

		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_6 + (0x100 * i), 0x00A493CF);

		/* Subcarrier Increment */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
	}

	/* set picture resolutions */
	/* 0 - 720 */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
	/* 0 - 576 */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);

	/* set Bypass input format to PAL 625 lines */
	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
	value &= 0xFFF7FDFF;
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);

	mutex_unlock(&dev->lock);

	return ret_val;
}

int medusa_set_videostandard(struct cx25821_dev *dev)
{
	int status = STATUS_SUCCESS;
	u32 value = 0, tmp = 0;

	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
		status = medusa_initialize_pal(dev);
	else
		status = medusa_initialize_ntsc(dev);

	/* Enable DENC_A output */
	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
	value = setBitAtPos(value, 4);
	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);

	/* Enable DENC_B output */
	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
	value = setBitAtPos(value, 4);
	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);

	return status;
}

void medusa_set_resolution(struct cx25821_dev *dev, int width,
			   int decoder_select)
{
	int decoder = 0;
	int decoder_count = 0;
	int ret_val = 0;
	u32 hscale = 0x0;
	u32 vscale = 0x0;
	const int MAX_WIDTH = 720;

	mutex_lock(&dev->lock);

	/* validate the width - cannot be negative */
	if (width > MAX_WIDTH) {
		pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
			__func__, width, MAX_WIDTH);
		width = MAX_WIDTH;
	}

	if (decoder_select <= 7 && decoder_select >= 0) {
		decoder = decoder_select;
		decoder_count = decoder_select + 1;
	} else {
		decoder = 0;
		decoder_count = _num_decoders;
	}

	switch (width) {
	case 320:
		hscale = 0x13E34B;
		vscale = 0x0;
		break;

	case 352:
		hscale = 0x10A273;
		vscale = 0x0;
		break;

	case 176:
		hscale = 0x3115B2;
		vscale = 0x1E00;
		break;

	case 160:
		hscale = 0x378D84;
		vscale = 0x1E00;
		break;

	default:		/* 720 */
		hscale = 0x0;
		vscale = 0x0;
		break;
	}

	for (; decoder < decoder_count; decoder++) {
		/* write scaling values for each decoder */
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      HSCALE_CTRL + (0x200 * decoder), hscale);
		ret_val =
		    cx25821_i2c_write(&dev->i2c_bus[0],
				      VSCALE_CTRL + (0x200 * decoder), vscale);
	}

	mutex_unlock(&dev->lock);
}

static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
				       int duration)
{
	int ret_val = 0;
	u32 fld_cnt = 0;
	u32 tmp = 0;
	u32 disp_cnt_reg = DISP_AB_CNT;

	mutex_lock(&dev->lock);

	/* no support */
	if (decoder < VDEC_A && decoder > VDEC_H) {
		mutex_unlock(&dev->lock);
		return;
	}

	switch (decoder) {
	default:
		break;
	case VDEC_C:
	case VDEC_D:
		disp_cnt_reg = DISP_CD_CNT;
		break;
	case VDEC_E:
	case VDEC_F:
		disp_cnt_reg = DISP_EF_CNT;
		break;
	case VDEC_G:
	case VDEC_H:
		disp_cnt_reg = DISP_GH_CNT;
		break;
	}

	_display_field_cnt[decoder] = duration;

	/* update hardware */
	fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);

	if (!(decoder % 2)) {	/* EVEN decoder */
		fld_cnt &= 0xFFFF0000;
		fld_cnt |= duration;
	} else {
		fld_cnt &= 0x0000FFFF;
		fld_cnt |= ((u32) duration) << 16;
	}

	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);

	mutex_unlock(&dev->lock);
}

/* Map to Medusa register setting */
static int mapM(int srcMin,
		int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
{
	int numerator;
	int denominator;
	int quotient;

	if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
		return -1;
	/*
	 * This is the overall expression used:
	 * *dstVal =
	 *   (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
	 * but we need to account for rounding so below we use the modulus
	 * operator to find the remainder and increment if necessary.
	 */
	numerator = (srcVal - srcMin) * (dstMax - dstMin);
	denominator = srcMax - srcMin;
	quotient = numerator / denominator;

	if (2 * (numerator % denominator) >= denominator)
		quotient++;

	*dstVal = quotient + dstMin;

	return 0;
}

static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
{
	unsigned char temp;

	if (numeric >= 0)
		return numeric;
	else {
		temp = ~(abs(numeric) & 0xFF);
		temp += 1;
		return temp;
	}
}

int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
{
	int ret_val = 0;
	int value = 0;
	u32 val = 0, tmp = 0;

	mutex_lock(&dev->lock);
	if ((brightness > VIDEO_PROCAMP_MAX)
	    || (brightness < VIDEO_PROCAMP_MIN)) {
		mutex_unlock(&dev->lock);
		return -1;
	}
	ret_val =
	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
		 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
	value = convert_to_twos(value, 8);
	val =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
	val &= 0xFFFFFF00;
	ret_val |=
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      VDEC_A_BRITE_CTRL + (0x200 * decoder),
			      val | value);
	mutex_unlock(&dev->lock);
	return ret_val;
}

int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
{
	int ret_val = 0;
	int value = 0;
	u32 val = 0, tmp = 0;

	mutex_lock(&dev->lock);

	if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
		mutex_unlock(&dev->lock);
		return -1;
	}

	ret_val =
	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
	val =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
	val &= 0xFFFFFF00;
	ret_val |=
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      VDEC_A_CNTRST_CTRL + (0x200 * decoder),
			      val | value);

	mutex_unlock(&dev->lock);
	return ret_val;
}

int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
{
	int ret_val = 0;
	int value = 0;
	u32 val = 0, tmp = 0;

	mutex_lock(&dev->lock);

	if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
		mutex_unlock(&dev->lock);
		return -1;
	}

	ret_val =
	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
		 SIGNED_BYTE_MAX, &value);

	value = convert_to_twos(value, 8);
	val =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
	val &= 0xFFFFFF00;

	ret_val |=
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);

	mutex_unlock(&dev->lock);
	return ret_val;
}

int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
{
	int ret_val = 0;
	int value = 0;
	u32 val = 0, tmp = 0;

	mutex_lock(&dev->lock);

	if ((saturation > VIDEO_PROCAMP_MAX)
	    || (saturation < VIDEO_PROCAMP_MIN)) {
		mutex_unlock(&dev->lock);
		return -1;
	}

	ret_val =
	    mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
		 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);

	val =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
	val &= 0xFFFFFF00;
	ret_val |=
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      VDEC_A_USAT_CTRL + (0x200 * decoder),
			      val | value);

	val =
	    cx25821_i2c_read(&dev->i2c_bus[0],
			     VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
	val &= 0xFFFFFF00;
	ret_val |=
	    cx25821_i2c_write(&dev->i2c_bus[0],
			      VDEC_A_VSAT_CTRL + (0x200 * decoder),
			      val | value);

	mutex_unlock(&dev->lock);
	return ret_val;
}

/* Program the display sequence and monitor output. */

int medusa_video_init(struct cx25821_dev *dev)
{
	u32 value = 0, tmp = 0;
	int ret_val = 0;
	int i = 0;

	mutex_lock(&dev->lock);

	_num_decoders = dev->_max_num_decoders;

	/* disable Auto source selection on all video decoders */
	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
	value &= 0xFFFFF0FF;
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);

	if (ret_val < 0)
		goto error;

	/* Turn off Master source switch enable */
	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
	value &= 0xFFFFFFDF;
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);

	if (ret_val < 0)
		goto error;

	mutex_unlock(&dev->lock);

	for (i = 0; i < _num_decoders; i++)
		medusa_set_decoderduration(dev, i, _display_field_cnt[i]);

	mutex_lock(&dev->lock);

	/* Select monitor as DENC A input, power up the DAC */
	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
	value &= 0xFF70FF70;
	value |= 0x00090008;	/* set en_active */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);

	if (ret_val < 0)
		goto error;

	/* enable input is VIP/656 */
	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
	value |= 0x00040100;	/* enable VIP */
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);

	if (ret_val < 0)
		goto error;

	/* select AFE clock to output mode */
	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
	value &= 0x83FFFFFF;
	ret_val =
	   cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
			     value | 0x10000000);

	if (ret_val < 0)
		goto error;

	/* Turn on all of the data out and control output pins. */
	value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
	value &= 0xFEF0FE00;
	if (_num_decoders == MAX_DECODERS) {
		/*
		 * Note: The octal board does not support control pins(bit16-19)
		 * These bits are ignored in the octal board.
		 *
		 * disable VDEC A-C port, default to Mobilygen Interface
		 */
		value |= 0x010001F8;
	} else {
		/* disable VDEC A-C port, default to Mobilygen Interface */
		value |= 0x010F0108;
	}

	value |= 7;
	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);

	if (ret_val < 0)
		goto error;


	mutex_unlock(&dev->lock);

	ret_val = medusa_set_videostandard(dev);

	return ret_val;

error:
	mutex_unlock(&dev->lock);
	return ret_val;
}
