162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  Driver for the Conexant CX25821 PCIe bridge
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 2009 Conexant Systems Inc.
662306a36Sopenharmony_ci *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "cx25821.h"
1262306a36Sopenharmony_ci#include "cx25821-medusa-video.h"
1362306a36Sopenharmony_ci#include "cx25821-biffuncs.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci/*
1662306a36Sopenharmony_ci * medusa_enable_bluefield_output()
1762306a36Sopenharmony_ci *
1862306a36Sopenharmony_ci * Enable the generation of blue filed output if no video
1962306a36Sopenharmony_ci *
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_cistatic void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
2262306a36Sopenharmony_ci					   int enable)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	u32 value = 0;
2562306a36Sopenharmony_ci	u32 tmp = 0;
2662306a36Sopenharmony_ci	int out_ctrl = OUT_CTRL1;
2762306a36Sopenharmony_ci	int out_ctrl_ns = OUT_CTRL_NS;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	switch (channel) {
3062306a36Sopenharmony_ci	default:
3162306a36Sopenharmony_ci	case VDEC_A:
3262306a36Sopenharmony_ci		break;
3362306a36Sopenharmony_ci	case VDEC_B:
3462306a36Sopenharmony_ci		out_ctrl = VDEC_B_OUT_CTRL1;
3562306a36Sopenharmony_ci		out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
3662306a36Sopenharmony_ci		break;
3762306a36Sopenharmony_ci	case VDEC_C:
3862306a36Sopenharmony_ci		out_ctrl = VDEC_C_OUT_CTRL1;
3962306a36Sopenharmony_ci		out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
4062306a36Sopenharmony_ci		break;
4162306a36Sopenharmony_ci	case VDEC_D:
4262306a36Sopenharmony_ci		out_ctrl = VDEC_D_OUT_CTRL1;
4362306a36Sopenharmony_ci		out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
4462306a36Sopenharmony_ci		break;
4562306a36Sopenharmony_ci	case VDEC_E:
4662306a36Sopenharmony_ci		out_ctrl = VDEC_E_OUT_CTRL1;
4762306a36Sopenharmony_ci		out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
4862306a36Sopenharmony_ci		return;
4962306a36Sopenharmony_ci	case VDEC_F:
5062306a36Sopenharmony_ci		out_ctrl = VDEC_F_OUT_CTRL1;
5162306a36Sopenharmony_ci		out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
5262306a36Sopenharmony_ci		return;
5362306a36Sopenharmony_ci	case VDEC_G:
5462306a36Sopenharmony_ci		out_ctrl = VDEC_G_OUT_CTRL1;
5562306a36Sopenharmony_ci		out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
5662306a36Sopenharmony_ci		return;
5762306a36Sopenharmony_ci	case VDEC_H:
5862306a36Sopenharmony_ci		out_ctrl = VDEC_H_OUT_CTRL1;
5962306a36Sopenharmony_ci		out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
6062306a36Sopenharmony_ci		return;
6162306a36Sopenharmony_ci	}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
6462306a36Sopenharmony_ci	value &= 0xFFFFFF7F;	/* clear BLUE_FIELD_EN */
6562306a36Sopenharmony_ci	if (enable)
6662306a36Sopenharmony_ci		value |= 0x00000080;	/* set BLUE_FIELD_EN */
6762306a36Sopenharmony_ci	cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
7062306a36Sopenharmony_ci	value &= 0xFFFFFF7F;
7162306a36Sopenharmony_ci	if (enable)
7262306a36Sopenharmony_ci		value |= 0x00000080;	/* set BLUE_FIELD_EN */
7362306a36Sopenharmony_ci	cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
7462306a36Sopenharmony_ci}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_cistatic int medusa_initialize_ntsc(struct cx25821_dev *dev)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	int ret_val = 0;
7962306a36Sopenharmony_ci	int i = 0;
8062306a36Sopenharmony_ci	u32 value = 0;
8162306a36Sopenharmony_ci	u32 tmp = 0;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	for (i = 0; i < MAX_DECODERS; i++) {
8462306a36Sopenharmony_ci		/* set video format NTSC-M */
8562306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
8662306a36Sopenharmony_ci				MODE_CTRL + (0x200 * i), &tmp);
8762306a36Sopenharmony_ci		value &= 0xFFFFFFF0;
8862306a36Sopenharmony_ci		/* enable the fast locking mode bit[16] */
8962306a36Sopenharmony_ci		value |= 0x10001;
9062306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
9162306a36Sopenharmony_ci				MODE_CTRL + (0x200 * i), value);
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci		/* resolution NTSC 720x480 */
9462306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
9562306a36Sopenharmony_ci				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
9662306a36Sopenharmony_ci		value &= 0x00C00C00;
9762306a36Sopenharmony_ci		value |= 0x612D0074;
9862306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
9962306a36Sopenharmony_ci				HORIZ_TIM_CTRL + (0x200 * i), value);
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
10262306a36Sopenharmony_ci				VERT_TIM_CTRL + (0x200 * i), &tmp);
10362306a36Sopenharmony_ci		value &= 0x00C00C00;
10462306a36Sopenharmony_ci		value |= 0x1C1E001A;	/* vblank_cnt + 2 to get camera ID */
10562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
10662306a36Sopenharmony_ci				VERT_TIM_CTRL + (0x200 * i), value);
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci		/* chroma subcarrier step size */
10962306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
11062306a36Sopenharmony_ci				SC_STEP_SIZE + (0x200 * i), 0x43E00000);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci		/* enable VIP optional active */
11362306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
11462306a36Sopenharmony_ci				OUT_CTRL_NS + (0x200 * i), &tmp);
11562306a36Sopenharmony_ci		value &= 0xFFFBFFFF;
11662306a36Sopenharmony_ci		value |= 0x00040000;
11762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
11862306a36Sopenharmony_ci				OUT_CTRL_NS + (0x200 * i), value);
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
12162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
12262306a36Sopenharmony_ci				OUT_CTRL1 + (0x200 * i), &tmp);
12362306a36Sopenharmony_ci		value &= 0xFFFBFFFF;
12462306a36Sopenharmony_ci		value |= 0x00040000;
12562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
12662306a36Sopenharmony_ci				OUT_CTRL1 + (0x200 * i), value);
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci		/*
12962306a36Sopenharmony_ci		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
13062306a36Sopenharmony_ci		 * when the input switching rate < 16 fields
13162306a36Sopenharmony_ci		*/
13262306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
13362306a36Sopenharmony_ci				MISC_TIM_CTRL + (0x200 * i), &tmp);
13462306a36Sopenharmony_ci		/* disable special play detection */
13562306a36Sopenharmony_ci		value = setBitAtPos(value, 14);
13662306a36Sopenharmony_ci		value = clearBitAtPos(value, 15);
13762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
13862306a36Sopenharmony_ci				MISC_TIM_CTRL + (0x200 * i), value);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci		/* set vbi_gate_en to 0 */
14162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
14262306a36Sopenharmony_ci				DFE_CTRL1 + (0x200 * i), &tmp);
14362306a36Sopenharmony_ci		value = clearBitAtPos(value, 29);
14462306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
14562306a36Sopenharmony_ci				DFE_CTRL1 + (0x200 * i), value);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		/* Enable the generation of blue field output if no video */
14862306a36Sopenharmony_ci		medusa_enable_bluefield_output(dev, i, 1);
14962306a36Sopenharmony_ci	}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	for (i = 0; i < MAX_ENCODERS; i++) {
15262306a36Sopenharmony_ci		/* NTSC hclock */
15362306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
15462306a36Sopenharmony_ci				DENC_A_REG_1 + (0x100 * i), &tmp);
15562306a36Sopenharmony_ci		value &= 0xF000FC00;
15662306a36Sopenharmony_ci		value |= 0x06B402D0;
15762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
15862306a36Sopenharmony_ci				DENC_A_REG_1 + (0x100 * i), value);
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci		/* burst begin and burst end */
16162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
16262306a36Sopenharmony_ci				DENC_A_REG_2 + (0x100 * i), &tmp);
16362306a36Sopenharmony_ci		value &= 0xFF000000;
16462306a36Sopenharmony_ci		value |= 0x007E9054;
16562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
16662306a36Sopenharmony_ci				DENC_A_REG_2 + (0x100 * i), value);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
16962306a36Sopenharmony_ci				DENC_A_REG_3 + (0x100 * i), &tmp);
17062306a36Sopenharmony_ci		value &= 0xFC00FE00;
17162306a36Sopenharmony_ci		value |= 0x00EC00F0;
17262306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
17362306a36Sopenharmony_ci				DENC_A_REG_3 + (0x100 * i), value);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci		/* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
17662306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
17762306a36Sopenharmony_ci				DENC_A_REG_4 + (0x100 * i), &tmp);
17862306a36Sopenharmony_ci		value &= 0x00FCFFFF;
17962306a36Sopenharmony_ci		value |= 0x13020000;
18062306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
18162306a36Sopenharmony_ci				DENC_A_REG_4 + (0x100 * i), value);
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
18462306a36Sopenharmony_ci				DENC_A_REG_5 + (0x100 * i), &tmp);
18562306a36Sopenharmony_ci		value &= 0xFFFF0000;
18662306a36Sopenharmony_ci		value |= 0x0000E575;
18762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
18862306a36Sopenharmony_ci				DENC_A_REG_5 + (0x100 * i), value);
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
19162306a36Sopenharmony_ci				DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci		/* Subcarrier Increment */
19462306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
19562306a36Sopenharmony_ci				DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
19662306a36Sopenharmony_ci	}
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	/* set picture resolutions */
19962306a36Sopenharmony_ci	/* 0 - 720 */
20062306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
20162306a36Sopenharmony_ci	/* 0 - 480 */
20262306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	/* set Bypass input format to NTSC 525 lines */
20562306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
20662306a36Sopenharmony_ci	value |= 0x00080200;
20762306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci	return ret_val;
21062306a36Sopenharmony_ci}
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_cistatic int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	int ret_val = -1;
21562306a36Sopenharmony_ci	u32 value = 0, tmp = 0;
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	/* Setup for 2D threshold */
21862306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
21962306a36Sopenharmony_ci			COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861);
22062306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
22162306a36Sopenharmony_ci			COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861);
22262306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
22362306a36Sopenharmony_ci			COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	/* Setup flat chroma and luma thresholds */
22662306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0],
22762306a36Sopenharmony_ci			COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
22862306a36Sopenharmony_ci	value &= 0x06230000;
22962306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
23062306a36Sopenharmony_ci			COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	/* set comb 2D blend */
23362306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
23462306a36Sopenharmony_ci			COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ci	/* COMB MISC CONTROL */
23762306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
23862306a36Sopenharmony_ci			COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	return ret_val;
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic int medusa_initialize_pal(struct cx25821_dev *dev)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	int ret_val = 0;
24662306a36Sopenharmony_ci	int i = 0;
24762306a36Sopenharmony_ci	u32 value = 0;
24862306a36Sopenharmony_ci	u32 tmp = 0;
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci	for (i = 0; i < MAX_DECODERS; i++) {
25162306a36Sopenharmony_ci		/* set video format PAL-BDGHI */
25262306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
25362306a36Sopenharmony_ci				MODE_CTRL + (0x200 * i), &tmp);
25462306a36Sopenharmony_ci		value &= 0xFFFFFFF0;
25562306a36Sopenharmony_ci		/* enable the fast locking mode bit[16] */
25662306a36Sopenharmony_ci		value |= 0x10004;
25762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
25862306a36Sopenharmony_ci				MODE_CTRL + (0x200 * i), value);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci		/* resolution PAL 720x576 */
26162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
26262306a36Sopenharmony_ci				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
26362306a36Sopenharmony_ci		value &= 0x00C00C00;
26462306a36Sopenharmony_ci		value |= 0x632D007D;
26562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
26662306a36Sopenharmony_ci				HORIZ_TIM_CTRL + (0x200 * i), value);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci		/* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
26962306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
27062306a36Sopenharmony_ci				VERT_TIM_CTRL + (0x200 * i), &tmp);
27162306a36Sopenharmony_ci		value &= 0x00C00C00;
27262306a36Sopenharmony_ci		value |= 0x28240026;	/* vblank_cnt + 2 to get camera ID */
27362306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
27462306a36Sopenharmony_ci				VERT_TIM_CTRL + (0x200 * i), value);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci		/* chroma subcarrier step size */
27762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
27862306a36Sopenharmony_ci				SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci		/* enable VIP optional active */
28162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
28262306a36Sopenharmony_ci				OUT_CTRL_NS + (0x200 * i), &tmp);
28362306a36Sopenharmony_ci		value &= 0xFFFBFFFF;
28462306a36Sopenharmony_ci		value |= 0x00040000;
28562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
28662306a36Sopenharmony_ci				OUT_CTRL_NS + (0x200 * i), value);
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
28962306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
29062306a36Sopenharmony_ci				OUT_CTRL1 + (0x200 * i), &tmp);
29162306a36Sopenharmony_ci		value &= 0xFFFBFFFF;
29262306a36Sopenharmony_ci		value |= 0x00040000;
29362306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
29462306a36Sopenharmony_ci				OUT_CTRL1 + (0x200 * i), value);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci		/*
29762306a36Sopenharmony_ci		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
29862306a36Sopenharmony_ci		 * when the input switching rate < 16 fields
29962306a36Sopenharmony_ci		 */
30062306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
30162306a36Sopenharmony_ci				MISC_TIM_CTRL + (0x200 * i), &tmp);
30262306a36Sopenharmony_ci		/* disable special play detection */
30362306a36Sopenharmony_ci		value = setBitAtPos(value, 14);
30462306a36Sopenharmony_ci		value = clearBitAtPos(value, 15);
30562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
30662306a36Sopenharmony_ci				MISC_TIM_CTRL + (0x200 * i), value);
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci		/* set vbi_gate_en to 0 */
30962306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
31062306a36Sopenharmony_ci				DFE_CTRL1 + (0x200 * i), &tmp);
31162306a36Sopenharmony_ci		value = clearBitAtPos(value, 29);
31262306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
31362306a36Sopenharmony_ci				DFE_CTRL1 + (0x200 * i), value);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci		medusa_PALCombInit(dev, i);
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_ci		/* Enable the generation of blue field output if no video */
31862306a36Sopenharmony_ci		medusa_enable_bluefield_output(dev, i, 1);
31962306a36Sopenharmony_ci	}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	for (i = 0; i < MAX_ENCODERS; i++) {
32262306a36Sopenharmony_ci		/* PAL hclock */
32362306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
32462306a36Sopenharmony_ci				DENC_A_REG_1 + (0x100 * i), &tmp);
32562306a36Sopenharmony_ci		value &= 0xF000FC00;
32662306a36Sopenharmony_ci		value |= 0x06C002D0;
32762306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
32862306a36Sopenharmony_ci				DENC_A_REG_1 + (0x100 * i), value);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci		/* burst begin and burst end */
33162306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
33262306a36Sopenharmony_ci				DENC_A_REG_2 + (0x100 * i), &tmp);
33362306a36Sopenharmony_ci		value &= 0xFF000000;
33462306a36Sopenharmony_ci		value |= 0x007E9754;
33562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
33662306a36Sopenharmony_ci				DENC_A_REG_2 + (0x100 * i), value);
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci		/* hblank and vactive */
33962306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
34062306a36Sopenharmony_ci				DENC_A_REG_3 + (0x100 * i), &tmp);
34162306a36Sopenharmony_ci		value &= 0xFC00FE00;
34262306a36Sopenharmony_ci		value |= 0x00FC0120;
34362306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
34462306a36Sopenharmony_ci				DENC_A_REG_3 + (0x100 * i), value);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci		/* set PAL vblank, phase alternation, 0 IRE pedestal */
34762306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
34862306a36Sopenharmony_ci				DENC_A_REG_4 + (0x100 * i), &tmp);
34962306a36Sopenharmony_ci		value &= 0x00FCFFFF;
35062306a36Sopenharmony_ci		value |= 0x14010000;
35162306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
35262306a36Sopenharmony_ci				DENC_A_REG_4 + (0x100 * i), value);
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci		value = cx25821_i2c_read(&dev->i2c_bus[0],
35562306a36Sopenharmony_ci				DENC_A_REG_5 + (0x100 * i), &tmp);
35662306a36Sopenharmony_ci		value &= 0xFFFF0000;
35762306a36Sopenharmony_ci		value |= 0x0000F078;
35862306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
35962306a36Sopenharmony_ci				DENC_A_REG_5 + (0x100 * i), value);
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
36262306a36Sopenharmony_ci				DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci		/* Subcarrier Increment */
36562306a36Sopenharmony_ci		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
36662306a36Sopenharmony_ci				DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	/* set picture resolutions */
37062306a36Sopenharmony_ci	/* 0 - 720 */
37162306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
37262306a36Sopenharmony_ci	/* 0 - 576 */
37362306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	/* set Bypass input format to PAL 625 lines */
37662306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
37762306a36Sopenharmony_ci	value &= 0xFFF7FDFF;
37862306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	return ret_val;
38162306a36Sopenharmony_ci}
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ciint medusa_set_videostandard(struct cx25821_dev *dev)
38462306a36Sopenharmony_ci{
38562306a36Sopenharmony_ci	int status = 0;
38662306a36Sopenharmony_ci	u32 value = 0, tmp = 0;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
38962306a36Sopenharmony_ci		status = medusa_initialize_pal(dev);
39062306a36Sopenharmony_ci	else
39162306a36Sopenharmony_ci		status = medusa_initialize_ntsc(dev);
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	/* Enable DENC_A output */
39462306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
39562306a36Sopenharmony_ci	value = setBitAtPos(value, 4);
39662306a36Sopenharmony_ci	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	/* Enable DENC_B output */
39962306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
40062306a36Sopenharmony_ci	value = setBitAtPos(value, 4);
40162306a36Sopenharmony_ci	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_ci	return status;
40462306a36Sopenharmony_ci}
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_civoid medusa_set_resolution(struct cx25821_dev *dev, int width,
40762306a36Sopenharmony_ci			   int decoder_select)
40862306a36Sopenharmony_ci{
40962306a36Sopenharmony_ci	int decoder = 0;
41062306a36Sopenharmony_ci	int decoder_count = 0;
41162306a36Sopenharmony_ci	u32 hscale = 0x0;
41262306a36Sopenharmony_ci	u32 vscale = 0x0;
41362306a36Sopenharmony_ci	const int MAX_WIDTH = 720;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	/* validate the width */
41662306a36Sopenharmony_ci	if (width > MAX_WIDTH) {
41762306a36Sopenharmony_ci		pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
41862306a36Sopenharmony_ci			__func__, width, MAX_WIDTH);
41962306a36Sopenharmony_ci		width = MAX_WIDTH;
42062306a36Sopenharmony_ci	}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	if (decoder_select <= 7 && decoder_select >= 0) {
42362306a36Sopenharmony_ci		decoder = decoder_select;
42462306a36Sopenharmony_ci		decoder_count = decoder_select + 1;
42562306a36Sopenharmony_ci	} else {
42662306a36Sopenharmony_ci		decoder = 0;
42762306a36Sopenharmony_ci		decoder_count = dev->_max_num_decoders;
42862306a36Sopenharmony_ci	}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	switch (width) {
43162306a36Sopenharmony_ci	case 320:
43262306a36Sopenharmony_ci		hscale = 0x13E34B;
43362306a36Sopenharmony_ci		vscale = 0x0;
43462306a36Sopenharmony_ci		break;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	case 352:
43762306a36Sopenharmony_ci		hscale = 0x10A273;
43862306a36Sopenharmony_ci		vscale = 0x0;
43962306a36Sopenharmony_ci		break;
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_ci	case 176:
44262306a36Sopenharmony_ci		hscale = 0x3115B2;
44362306a36Sopenharmony_ci		vscale = 0x1E00;
44462306a36Sopenharmony_ci		break;
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci	case 160:
44762306a36Sopenharmony_ci		hscale = 0x378D84;
44862306a36Sopenharmony_ci		vscale = 0x1E00;
44962306a36Sopenharmony_ci		break;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	default:		/* 720 */
45262306a36Sopenharmony_ci		hscale = 0x0;
45362306a36Sopenharmony_ci		vscale = 0x0;
45462306a36Sopenharmony_ci		break;
45562306a36Sopenharmony_ci	}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	for (; decoder < decoder_count; decoder++) {
45862306a36Sopenharmony_ci		/* write scaling values for each decoder */
45962306a36Sopenharmony_ci		cx25821_i2c_write(&dev->i2c_bus[0],
46062306a36Sopenharmony_ci				HSCALE_CTRL + (0x200 * decoder), hscale);
46162306a36Sopenharmony_ci		cx25821_i2c_write(&dev->i2c_bus[0],
46262306a36Sopenharmony_ci				VSCALE_CTRL + (0x200 * decoder), vscale);
46362306a36Sopenharmony_ci	}
46462306a36Sopenharmony_ci}
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_cistatic void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
46762306a36Sopenharmony_ci				       int duration)
46862306a36Sopenharmony_ci{
46962306a36Sopenharmony_ci	u32 fld_cnt = 0;
47062306a36Sopenharmony_ci	u32 tmp = 0;
47162306a36Sopenharmony_ci	u32 disp_cnt_reg = DISP_AB_CNT;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	/* no support */
47462306a36Sopenharmony_ci	if (decoder < VDEC_A || decoder > VDEC_H) {
47562306a36Sopenharmony_ci		return;
47662306a36Sopenharmony_ci	}
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	switch (decoder) {
47962306a36Sopenharmony_ci	default:
48062306a36Sopenharmony_ci		break;
48162306a36Sopenharmony_ci	case VDEC_C:
48262306a36Sopenharmony_ci	case VDEC_D:
48362306a36Sopenharmony_ci		disp_cnt_reg = DISP_CD_CNT;
48462306a36Sopenharmony_ci		break;
48562306a36Sopenharmony_ci	case VDEC_E:
48662306a36Sopenharmony_ci	case VDEC_F:
48762306a36Sopenharmony_ci		disp_cnt_reg = DISP_EF_CNT;
48862306a36Sopenharmony_ci		break;
48962306a36Sopenharmony_ci	case VDEC_G:
49062306a36Sopenharmony_ci	case VDEC_H:
49162306a36Sopenharmony_ci		disp_cnt_reg = DISP_GH_CNT;
49262306a36Sopenharmony_ci		break;
49362306a36Sopenharmony_ci	}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	/* update hardware */
49662306a36Sopenharmony_ci	fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
49762306a36Sopenharmony_ci
49862306a36Sopenharmony_ci	if (!(decoder % 2)) {	/* EVEN decoder */
49962306a36Sopenharmony_ci		fld_cnt &= 0xFFFF0000;
50062306a36Sopenharmony_ci		fld_cnt |= duration;
50162306a36Sopenharmony_ci	} else {
50262306a36Sopenharmony_ci		fld_cnt &= 0x0000FFFF;
50362306a36Sopenharmony_ci		fld_cnt |= ((u32) duration) << 16;
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
50762306a36Sopenharmony_ci}
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci/* Map to Medusa register setting */
51062306a36Sopenharmony_cistatic int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
51162306a36Sopenharmony_ci		int *dstVal)
51262306a36Sopenharmony_ci{
51362306a36Sopenharmony_ci	int numerator;
51462306a36Sopenharmony_ci	int denominator;
51562306a36Sopenharmony_ci	int quotient;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
51862306a36Sopenharmony_ci		return -1;
51962306a36Sopenharmony_ci	/*
52062306a36Sopenharmony_ci	 * This is the overall expression used:
52162306a36Sopenharmony_ci	 * *dstVal =
52262306a36Sopenharmony_ci	 *   (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
52362306a36Sopenharmony_ci	 * but we need to account for rounding so below we use the modulus
52462306a36Sopenharmony_ci	 * operator to find the remainder and increment if necessary.
52562306a36Sopenharmony_ci	 */
52662306a36Sopenharmony_ci	numerator = (srcVal - srcMin) * (dstMax - dstMin);
52762306a36Sopenharmony_ci	denominator = srcMax - srcMin;
52862306a36Sopenharmony_ci	quotient = numerator / denominator;
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	if (2 * (numerator % denominator) >= denominator)
53162306a36Sopenharmony_ci		quotient++;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	*dstVal = quotient + dstMin;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	return 0;
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci
53862306a36Sopenharmony_cistatic unsigned long convert_to_twos(long numeric, unsigned long bits_len)
53962306a36Sopenharmony_ci{
54062306a36Sopenharmony_ci	unsigned char temp;
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	if (numeric >= 0)
54362306a36Sopenharmony_ci		return numeric;
54462306a36Sopenharmony_ci	else {
54562306a36Sopenharmony_ci		temp = ~(abs(numeric) & 0xFF);
54662306a36Sopenharmony_ci		temp += 1;
54762306a36Sopenharmony_ci		return temp;
54862306a36Sopenharmony_ci	}
54962306a36Sopenharmony_ci}
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ciint medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
55262306a36Sopenharmony_ci{
55362306a36Sopenharmony_ci	int ret_val = 0;
55462306a36Sopenharmony_ci	int value = 0;
55562306a36Sopenharmony_ci	u32 val = 0, tmp = 0;
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	if ((brightness > VIDEO_PROCAMP_MAX) ||
55862306a36Sopenharmony_ci	    (brightness < VIDEO_PROCAMP_MIN)) {
55962306a36Sopenharmony_ci		return -1;
56062306a36Sopenharmony_ci	}
56162306a36Sopenharmony_ci	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
56262306a36Sopenharmony_ci			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
56362306a36Sopenharmony_ci	value = convert_to_twos(value, 8);
56462306a36Sopenharmony_ci	val = cx25821_i2c_read(&dev->i2c_bus[0],
56562306a36Sopenharmony_ci			VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
56662306a36Sopenharmony_ci	val &= 0xFFFFFF00;
56762306a36Sopenharmony_ci	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
56862306a36Sopenharmony_ci			VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
56962306a36Sopenharmony_ci	return ret_val;
57062306a36Sopenharmony_ci}
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ciint medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
57362306a36Sopenharmony_ci{
57462306a36Sopenharmony_ci	int ret_val = 0;
57562306a36Sopenharmony_ci	int value = 0;
57662306a36Sopenharmony_ci	u32 val = 0, tmp = 0;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
57962306a36Sopenharmony_ci		return -1;
58062306a36Sopenharmony_ci	}
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
58362306a36Sopenharmony_ci			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
58462306a36Sopenharmony_ci	val = cx25821_i2c_read(&dev->i2c_bus[0],
58562306a36Sopenharmony_ci			VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
58662306a36Sopenharmony_ci	val &= 0xFFFFFF00;
58762306a36Sopenharmony_ci	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
58862306a36Sopenharmony_ci			VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci	return ret_val;
59162306a36Sopenharmony_ci}
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_ciint medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
59462306a36Sopenharmony_ci{
59562306a36Sopenharmony_ci	int ret_val = 0;
59662306a36Sopenharmony_ci	int value = 0;
59762306a36Sopenharmony_ci	u32 val = 0, tmp = 0;
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci	if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
60062306a36Sopenharmony_ci		return -1;
60162306a36Sopenharmony_ci	}
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
60462306a36Sopenharmony_ci			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	value = convert_to_twos(value, 8);
60762306a36Sopenharmony_ci	val = cx25821_i2c_read(&dev->i2c_bus[0],
60862306a36Sopenharmony_ci			VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
60962306a36Sopenharmony_ci	val &= 0xFFFFFF00;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
61262306a36Sopenharmony_ci			VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	return ret_val;
61562306a36Sopenharmony_ci}
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ciint medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
61862306a36Sopenharmony_ci{
61962306a36Sopenharmony_ci	int ret_val = 0;
62062306a36Sopenharmony_ci	int value = 0;
62162306a36Sopenharmony_ci	u32 val = 0, tmp = 0;
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	if ((saturation > VIDEO_PROCAMP_MAX) ||
62462306a36Sopenharmony_ci	    (saturation < VIDEO_PROCAMP_MIN)) {
62562306a36Sopenharmony_ci		return -1;
62662306a36Sopenharmony_ci	}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
62962306a36Sopenharmony_ci			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	val = cx25821_i2c_read(&dev->i2c_bus[0],
63262306a36Sopenharmony_ci			VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
63362306a36Sopenharmony_ci	val &= 0xFFFFFF00;
63462306a36Sopenharmony_ci	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
63562306a36Sopenharmony_ci			VDEC_A_USAT_CTRL + (0x200 * decoder), val | value);
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	val = cx25821_i2c_read(&dev->i2c_bus[0],
63862306a36Sopenharmony_ci			VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
63962306a36Sopenharmony_ci	val &= 0xFFFFFF00;
64062306a36Sopenharmony_ci	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
64162306a36Sopenharmony_ci			VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	return ret_val;
64462306a36Sopenharmony_ci}
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci/* Program the display sequence and monitor output. */
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ciint medusa_video_init(struct cx25821_dev *dev)
64962306a36Sopenharmony_ci{
65062306a36Sopenharmony_ci	u32 value = 0, tmp = 0;
65162306a36Sopenharmony_ci	int ret_val = 0;
65262306a36Sopenharmony_ci	int i = 0;
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	/* disable Auto source selection on all video decoders */
65562306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
65662306a36Sopenharmony_ci	value &= 0xFFFFF0FF;
65762306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	if (ret_val < 0)
66062306a36Sopenharmony_ci		goto error;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	/* Turn off Master source switch enable */
66362306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
66462306a36Sopenharmony_ci	value &= 0xFFFFFFDF;
66562306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	if (ret_val < 0)
66862306a36Sopenharmony_ci		goto error;
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	/*
67162306a36Sopenharmony_ci	 * FIXME: due to a coding bug the duration was always 0. It's
67262306a36Sopenharmony_ci	 * likely that it really should be something else, but due to the
67362306a36Sopenharmony_ci	 * lack of documentation I have no idea what it should be. For
67462306a36Sopenharmony_ci	 * now just fill in 0 as the duration.
67562306a36Sopenharmony_ci	 */
67662306a36Sopenharmony_ci	for (i = 0; i < dev->_max_num_decoders; i++)
67762306a36Sopenharmony_ci		medusa_set_decoderduration(dev, i, 0);
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	/* Select monitor as DENC A input, power up the DAC */
68062306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
68162306a36Sopenharmony_ci	value &= 0xFF70FF70;
68262306a36Sopenharmony_ci	value |= 0x00090008;	/* set en_active */
68362306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci	if (ret_val < 0)
68662306a36Sopenharmony_ci		goto error;
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	/* enable input is VIP/656 */
68962306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
69062306a36Sopenharmony_ci	value |= 0x00040100;	/* enable VIP */
69162306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	if (ret_val < 0)
69462306a36Sopenharmony_ci		goto error;
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	/* select AFE clock to output mode */
69762306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
69862306a36Sopenharmony_ci	value &= 0x83FFFFFF;
69962306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
70062306a36Sopenharmony_ci			value | 0x10000000);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	if (ret_val < 0)
70362306a36Sopenharmony_ci		goto error;
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	/* Turn on all of the data out and control output pins. */
70662306a36Sopenharmony_ci	value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
70762306a36Sopenharmony_ci	value &= 0xFEF0FE00;
70862306a36Sopenharmony_ci	if (dev->_max_num_decoders == MAX_DECODERS) {
70962306a36Sopenharmony_ci		/*
71062306a36Sopenharmony_ci		 * Note: The octal board does not support control pins(bit16-19)
71162306a36Sopenharmony_ci		 * These bits are ignored in the octal board.
71262306a36Sopenharmony_ci		 *
71362306a36Sopenharmony_ci		 * disable VDEC A-C port, default to Mobilygen Interface
71462306a36Sopenharmony_ci		 */
71562306a36Sopenharmony_ci		value |= 0x010001F8;
71662306a36Sopenharmony_ci	} else {
71762306a36Sopenharmony_ci		/* disable VDEC A-C port, default to Mobilygen Interface */
71862306a36Sopenharmony_ci		value |= 0x010F0108;
71962306a36Sopenharmony_ci	}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_ci	value |= 7;
72262306a36Sopenharmony_ci	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	if (ret_val < 0)
72562306a36Sopenharmony_ci		goto error;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	ret_val = medusa_set_videostandard(dev);
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_cierror:
73062306a36Sopenharmony_ci	return ret_val;
73162306a36Sopenharmony_ci}
732