cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cx25821-medusa-video.c (19964B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Driver for the Conexant CX25821 PCIe bridge
      4 *
      5 *  Copyright (C) 2009 Conexant Systems Inc.
      6 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
      7 */
      8
      9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     10
     11#include "cx25821.h"
     12#include "cx25821-medusa-video.h"
     13#include "cx25821-biffuncs.h"
     14
     15/*
     16 * medusa_enable_bluefield_output()
     17 *
     18 * Enable the generation of blue filed output if no video
     19 *
     20 */
     21static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
     22					   int enable)
     23{
     24	u32 value = 0;
     25	u32 tmp = 0;
     26	int out_ctrl = OUT_CTRL1;
     27	int out_ctrl_ns = OUT_CTRL_NS;
     28
     29	switch (channel) {
     30	default:
     31	case VDEC_A:
     32		break;
     33	case VDEC_B:
     34		out_ctrl = VDEC_B_OUT_CTRL1;
     35		out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
     36		break;
     37	case VDEC_C:
     38		out_ctrl = VDEC_C_OUT_CTRL1;
     39		out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
     40		break;
     41	case VDEC_D:
     42		out_ctrl = VDEC_D_OUT_CTRL1;
     43		out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
     44		break;
     45	case VDEC_E:
     46		out_ctrl = VDEC_E_OUT_CTRL1;
     47		out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
     48		return;
     49	case VDEC_F:
     50		out_ctrl = VDEC_F_OUT_CTRL1;
     51		out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
     52		return;
     53	case VDEC_G:
     54		out_ctrl = VDEC_G_OUT_CTRL1;
     55		out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
     56		return;
     57	case VDEC_H:
     58		out_ctrl = VDEC_H_OUT_CTRL1;
     59		out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
     60		return;
     61	}
     62
     63	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
     64	value &= 0xFFFFFF7F;	/* clear BLUE_FIELD_EN */
     65	if (enable)
     66		value |= 0x00000080;	/* set BLUE_FIELD_EN */
     67	cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
     68
     69	value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
     70	value &= 0xFFFFFF7F;
     71	if (enable)
     72		value |= 0x00000080;	/* set BLUE_FIELD_EN */
     73	cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
     74}
     75
     76static int medusa_initialize_ntsc(struct cx25821_dev *dev)
     77{
     78	int ret_val = 0;
     79	int i = 0;
     80	u32 value = 0;
     81	u32 tmp = 0;
     82
     83	for (i = 0; i < MAX_DECODERS; i++) {
     84		/* set video format NTSC-M */
     85		value = cx25821_i2c_read(&dev->i2c_bus[0],
     86				MODE_CTRL + (0x200 * i), &tmp);
     87		value &= 0xFFFFFFF0;
     88		/* enable the fast locking mode bit[16] */
     89		value |= 0x10001;
     90		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
     91				MODE_CTRL + (0x200 * i), value);
     92
     93		/* resolution NTSC 720x480 */
     94		value = cx25821_i2c_read(&dev->i2c_bus[0],
     95				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
     96		value &= 0x00C00C00;
     97		value |= 0x612D0074;
     98		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
     99				HORIZ_TIM_CTRL + (0x200 * i), value);
    100
    101		value = cx25821_i2c_read(&dev->i2c_bus[0],
    102				VERT_TIM_CTRL + (0x200 * i), &tmp);
    103		value &= 0x00C00C00;
    104		value |= 0x1C1E001A;	/* vblank_cnt + 2 to get camera ID */
    105		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    106				VERT_TIM_CTRL + (0x200 * i), value);
    107
    108		/* chroma subcarrier step size */
    109		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    110				SC_STEP_SIZE + (0x200 * i), 0x43E00000);
    111
    112		/* enable VIP optional active */
    113		value = cx25821_i2c_read(&dev->i2c_bus[0],
    114				OUT_CTRL_NS + (0x200 * i), &tmp);
    115		value &= 0xFFFBFFFF;
    116		value |= 0x00040000;
    117		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    118				OUT_CTRL_NS + (0x200 * i), value);
    119
    120		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
    121		value = cx25821_i2c_read(&dev->i2c_bus[0],
    122				OUT_CTRL1 + (0x200 * i), &tmp);
    123		value &= 0xFFFBFFFF;
    124		value |= 0x00040000;
    125		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    126				OUT_CTRL1 + (0x200 * i), value);
    127
    128		/*
    129		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
    130		 * when the input switching rate < 16 fields
    131		*/
    132		value = cx25821_i2c_read(&dev->i2c_bus[0],
    133				MISC_TIM_CTRL + (0x200 * i), &tmp);
    134		/* disable special play detection */
    135		value = setBitAtPos(value, 14);
    136		value = clearBitAtPos(value, 15);
    137		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    138				MISC_TIM_CTRL + (0x200 * i), value);
    139
    140		/* set vbi_gate_en to 0 */
    141		value = cx25821_i2c_read(&dev->i2c_bus[0],
    142				DFE_CTRL1 + (0x200 * i), &tmp);
    143		value = clearBitAtPos(value, 29);
    144		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    145				DFE_CTRL1 + (0x200 * i), value);
    146
    147		/* Enable the generation of blue field output if no video */
    148		medusa_enable_bluefield_output(dev, i, 1);
    149	}
    150
    151	for (i = 0; i < MAX_ENCODERS; i++) {
    152		/* NTSC hclock */
    153		value = cx25821_i2c_read(&dev->i2c_bus[0],
    154				DENC_A_REG_1 + (0x100 * i), &tmp);
    155		value &= 0xF000FC00;
    156		value |= 0x06B402D0;
    157		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    158				DENC_A_REG_1 + (0x100 * i), value);
    159
    160		/* burst begin and burst end */
    161		value = cx25821_i2c_read(&dev->i2c_bus[0],
    162				DENC_A_REG_2 + (0x100 * i), &tmp);
    163		value &= 0xFF000000;
    164		value |= 0x007E9054;
    165		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    166				DENC_A_REG_2 + (0x100 * i), value);
    167
    168		value = cx25821_i2c_read(&dev->i2c_bus[0],
    169				DENC_A_REG_3 + (0x100 * i), &tmp);
    170		value &= 0xFC00FE00;
    171		value |= 0x00EC00F0;
    172		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    173				DENC_A_REG_3 + (0x100 * i), value);
    174
    175		/* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
    176		value = cx25821_i2c_read(&dev->i2c_bus[0],
    177				DENC_A_REG_4 + (0x100 * i), &tmp);
    178		value &= 0x00FCFFFF;
    179		value |= 0x13020000;
    180		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    181				DENC_A_REG_4 + (0x100 * i), value);
    182
    183		value = cx25821_i2c_read(&dev->i2c_bus[0],
    184				DENC_A_REG_5 + (0x100 * i), &tmp);
    185		value &= 0xFFFF0000;
    186		value |= 0x0000E575;
    187		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    188				DENC_A_REG_5 + (0x100 * i), value);
    189
    190		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    191				DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
    192
    193		/* Subcarrier Increment */
    194		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    195				DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
    196	}
    197
    198	/* set picture resolutions */
    199	/* 0 - 720 */
    200	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
    201	/* 0 - 480 */
    202	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
    203
    204	/* set Bypass input format to NTSC 525 lines */
    205	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
    206	value |= 0x00080200;
    207	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
    208
    209	return ret_val;
    210}
    211
    212static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
    213{
    214	int ret_val = -1;
    215	u32 value = 0, tmp = 0;
    216
    217	/* Setup for 2D threshold */
    218	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    219			COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861);
    220	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    221			COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861);
    222	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    223			COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023);
    224
    225	/* Setup flat chroma and luma thresholds */
    226	value = cx25821_i2c_read(&dev->i2c_bus[0],
    227			COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
    228	value &= 0x06230000;
    229	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    230			COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
    231
    232	/* set comb 2D blend */
    233	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    234			COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
    235
    236	/* COMB MISC CONTROL */
    237	ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    238			COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
    239
    240	return ret_val;
    241}
    242
    243static int medusa_initialize_pal(struct cx25821_dev *dev)
    244{
    245	int ret_val = 0;
    246	int i = 0;
    247	u32 value = 0;
    248	u32 tmp = 0;
    249
    250	for (i = 0; i < MAX_DECODERS; i++) {
    251		/* set video format PAL-BDGHI */
    252		value = cx25821_i2c_read(&dev->i2c_bus[0],
    253				MODE_CTRL + (0x200 * i), &tmp);
    254		value &= 0xFFFFFFF0;
    255		/* enable the fast locking mode bit[16] */
    256		value |= 0x10004;
    257		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    258				MODE_CTRL + (0x200 * i), value);
    259
    260		/* resolution PAL 720x576 */
    261		value = cx25821_i2c_read(&dev->i2c_bus[0],
    262				HORIZ_TIM_CTRL + (0x200 * i), &tmp);
    263		value &= 0x00C00C00;
    264		value |= 0x632D007D;
    265		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    266				HORIZ_TIM_CTRL + (0x200 * i), value);
    267
    268		/* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
    269		value = cx25821_i2c_read(&dev->i2c_bus[0],
    270				VERT_TIM_CTRL + (0x200 * i), &tmp);
    271		value &= 0x00C00C00;
    272		value |= 0x28240026;	/* vblank_cnt + 2 to get camera ID */
    273		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    274				VERT_TIM_CTRL + (0x200 * i), value);
    275
    276		/* chroma subcarrier step size */
    277		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    278				SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
    279
    280		/* enable VIP optional active */
    281		value = cx25821_i2c_read(&dev->i2c_bus[0],
    282				OUT_CTRL_NS + (0x200 * i), &tmp);
    283		value &= 0xFFFBFFFF;
    284		value |= 0x00040000;
    285		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    286				OUT_CTRL_NS + (0x200 * i), value);
    287
    288		/* enable VIP optional active (VIP_OPT_AL) for direct output. */
    289		value = cx25821_i2c_read(&dev->i2c_bus[0],
    290				OUT_CTRL1 + (0x200 * i), &tmp);
    291		value &= 0xFFFBFFFF;
    292		value |= 0x00040000;
    293		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    294				OUT_CTRL1 + (0x200 * i), value);
    295
    296		/*
    297		 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
    298		 * when the input switching rate < 16 fields
    299		 */
    300		value = cx25821_i2c_read(&dev->i2c_bus[0],
    301				MISC_TIM_CTRL + (0x200 * i), &tmp);
    302		/* disable special play detection */
    303		value = setBitAtPos(value, 14);
    304		value = clearBitAtPos(value, 15);
    305		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    306				MISC_TIM_CTRL + (0x200 * i), value);
    307
    308		/* set vbi_gate_en to 0 */
    309		value = cx25821_i2c_read(&dev->i2c_bus[0],
    310				DFE_CTRL1 + (0x200 * i), &tmp);
    311		value = clearBitAtPos(value, 29);
    312		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    313				DFE_CTRL1 + (0x200 * i), value);
    314
    315		medusa_PALCombInit(dev, i);
    316
    317		/* Enable the generation of blue field output if no video */
    318		medusa_enable_bluefield_output(dev, i, 1);
    319	}
    320
    321	for (i = 0; i < MAX_ENCODERS; i++) {
    322		/* PAL hclock */
    323		value = cx25821_i2c_read(&dev->i2c_bus[0],
    324				DENC_A_REG_1 + (0x100 * i), &tmp);
    325		value &= 0xF000FC00;
    326		value |= 0x06C002D0;
    327		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    328				DENC_A_REG_1 + (0x100 * i), value);
    329
    330		/* burst begin and burst end */
    331		value = cx25821_i2c_read(&dev->i2c_bus[0],
    332				DENC_A_REG_2 + (0x100 * i), &tmp);
    333		value &= 0xFF000000;
    334		value |= 0x007E9754;
    335		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    336				DENC_A_REG_2 + (0x100 * i), value);
    337
    338		/* hblank and vactive */
    339		value = cx25821_i2c_read(&dev->i2c_bus[0],
    340				DENC_A_REG_3 + (0x100 * i), &tmp);
    341		value &= 0xFC00FE00;
    342		value |= 0x00FC0120;
    343		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    344				DENC_A_REG_3 + (0x100 * i), value);
    345
    346		/* set PAL vblank, phase alternation, 0 IRE pedestal */
    347		value = cx25821_i2c_read(&dev->i2c_bus[0],
    348				DENC_A_REG_4 + (0x100 * i), &tmp);
    349		value &= 0x00FCFFFF;
    350		value |= 0x14010000;
    351		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    352				DENC_A_REG_4 + (0x100 * i), value);
    353
    354		value = cx25821_i2c_read(&dev->i2c_bus[0],
    355				DENC_A_REG_5 + (0x100 * i), &tmp);
    356		value &= 0xFFFF0000;
    357		value |= 0x0000F078;
    358		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    359				DENC_A_REG_5 + (0x100 * i), value);
    360
    361		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    362				DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
    363
    364		/* Subcarrier Increment */
    365		ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
    366				DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
    367	}
    368
    369	/* set picture resolutions */
    370	/* 0 - 720 */
    371	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
    372	/* 0 - 576 */
    373	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
    374
    375	/* set Bypass input format to PAL 625 lines */
    376	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
    377	value &= 0xFFF7FDFF;
    378	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
    379
    380	return ret_val;
    381}
    382
    383int medusa_set_videostandard(struct cx25821_dev *dev)
    384{
    385	int status = 0;
    386	u32 value = 0, tmp = 0;
    387
    388	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
    389		status = medusa_initialize_pal(dev);
    390	else
    391		status = medusa_initialize_ntsc(dev);
    392
    393	/* Enable DENC_A output */
    394	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
    395	value = setBitAtPos(value, 4);
    396	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
    397
    398	/* Enable DENC_B output */
    399	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
    400	value = setBitAtPos(value, 4);
    401	status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
    402
    403	return status;
    404}
    405
    406void medusa_set_resolution(struct cx25821_dev *dev, int width,
    407			   int decoder_select)
    408{
    409	int decoder = 0;
    410	int decoder_count = 0;
    411	u32 hscale = 0x0;
    412	u32 vscale = 0x0;
    413	const int MAX_WIDTH = 720;
    414
    415	/* validate the width */
    416	if (width > MAX_WIDTH) {
    417		pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
    418			__func__, width, MAX_WIDTH);
    419		width = MAX_WIDTH;
    420	}
    421
    422	if (decoder_select <= 7 && decoder_select >= 0) {
    423		decoder = decoder_select;
    424		decoder_count = decoder_select + 1;
    425	} else {
    426		decoder = 0;
    427		decoder_count = dev->_max_num_decoders;
    428	}
    429
    430	switch (width) {
    431	case 320:
    432		hscale = 0x13E34B;
    433		vscale = 0x0;
    434		break;
    435
    436	case 352:
    437		hscale = 0x10A273;
    438		vscale = 0x0;
    439		break;
    440
    441	case 176:
    442		hscale = 0x3115B2;
    443		vscale = 0x1E00;
    444		break;
    445
    446	case 160:
    447		hscale = 0x378D84;
    448		vscale = 0x1E00;
    449		break;
    450
    451	default:		/* 720 */
    452		hscale = 0x0;
    453		vscale = 0x0;
    454		break;
    455	}
    456
    457	for (; decoder < decoder_count; decoder++) {
    458		/* write scaling values for each decoder */
    459		cx25821_i2c_write(&dev->i2c_bus[0],
    460				HSCALE_CTRL + (0x200 * decoder), hscale);
    461		cx25821_i2c_write(&dev->i2c_bus[0],
    462				VSCALE_CTRL + (0x200 * decoder), vscale);
    463	}
    464}
    465
    466static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
    467				       int duration)
    468{
    469	u32 fld_cnt = 0;
    470	u32 tmp = 0;
    471	u32 disp_cnt_reg = DISP_AB_CNT;
    472
    473	/* no support */
    474	if (decoder < VDEC_A || decoder > VDEC_H) {
    475		return;
    476	}
    477
    478	switch (decoder) {
    479	default:
    480		break;
    481	case VDEC_C:
    482	case VDEC_D:
    483		disp_cnt_reg = DISP_CD_CNT;
    484		break;
    485	case VDEC_E:
    486	case VDEC_F:
    487		disp_cnt_reg = DISP_EF_CNT;
    488		break;
    489	case VDEC_G:
    490	case VDEC_H:
    491		disp_cnt_reg = DISP_GH_CNT;
    492		break;
    493	}
    494
    495	/* update hardware */
    496	fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
    497
    498	if (!(decoder % 2)) {	/* EVEN decoder */
    499		fld_cnt &= 0xFFFF0000;
    500		fld_cnt |= duration;
    501	} else {
    502		fld_cnt &= 0x0000FFFF;
    503		fld_cnt |= ((u32) duration) << 16;
    504	}
    505
    506	cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
    507}
    508
    509/* Map to Medusa register setting */
    510static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
    511		int *dstVal)
    512{
    513	int numerator;
    514	int denominator;
    515	int quotient;
    516
    517	if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
    518		return -1;
    519	/*
    520	 * This is the overall expression used:
    521	 * *dstVal =
    522	 *   (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
    523	 * but we need to account for rounding so below we use the modulus
    524	 * operator to find the remainder and increment if necessary.
    525	 */
    526	numerator = (srcVal - srcMin) * (dstMax - dstMin);
    527	denominator = srcMax - srcMin;
    528	quotient = numerator / denominator;
    529
    530	if (2 * (numerator % denominator) >= denominator)
    531		quotient++;
    532
    533	*dstVal = quotient + dstMin;
    534
    535	return 0;
    536}
    537
    538static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
    539{
    540	unsigned char temp;
    541
    542	if (numeric >= 0)
    543		return numeric;
    544	else {
    545		temp = ~(abs(numeric) & 0xFF);
    546		temp += 1;
    547		return temp;
    548	}
    549}
    550
    551int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
    552{
    553	int ret_val = 0;
    554	int value = 0;
    555	u32 val = 0, tmp = 0;
    556
    557	if ((brightness > VIDEO_PROCAMP_MAX) ||
    558	    (brightness < VIDEO_PROCAMP_MIN)) {
    559		return -1;
    560	}
    561	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
    562			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
    563	value = convert_to_twos(value, 8);
    564	val = cx25821_i2c_read(&dev->i2c_bus[0],
    565			VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
    566	val &= 0xFFFFFF00;
    567	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
    568			VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
    569	return ret_val;
    570}
    571
    572int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
    573{
    574	int ret_val = 0;
    575	int value = 0;
    576	u32 val = 0, tmp = 0;
    577
    578	if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
    579		return -1;
    580	}
    581
    582	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
    583			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
    584	val = cx25821_i2c_read(&dev->i2c_bus[0],
    585			VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
    586	val &= 0xFFFFFF00;
    587	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
    588			VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
    589
    590	return ret_val;
    591}
    592
    593int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
    594{
    595	int ret_val = 0;
    596	int value = 0;
    597	u32 val = 0, tmp = 0;
    598
    599	if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
    600		return -1;
    601	}
    602
    603	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
    604			SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
    605
    606	value = convert_to_twos(value, 8);
    607	val = cx25821_i2c_read(&dev->i2c_bus[0],
    608			VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
    609	val &= 0xFFFFFF00;
    610
    611	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
    612			VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
    613
    614	return ret_val;
    615}
    616
    617int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
    618{
    619	int ret_val = 0;
    620	int value = 0;
    621	u32 val = 0, tmp = 0;
    622
    623	if ((saturation > VIDEO_PROCAMP_MAX) ||
    624	    (saturation < VIDEO_PROCAMP_MIN)) {
    625		return -1;
    626	}
    627
    628	ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
    629			UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
    630
    631	val = cx25821_i2c_read(&dev->i2c_bus[0],
    632			VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
    633	val &= 0xFFFFFF00;
    634	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
    635			VDEC_A_USAT_CTRL + (0x200 * decoder), val | value);
    636
    637	val = cx25821_i2c_read(&dev->i2c_bus[0],
    638			VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
    639	val &= 0xFFFFFF00;
    640	ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
    641			VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
    642
    643	return ret_val;
    644}
    645
    646/* Program the display sequence and monitor output. */
    647
    648int medusa_video_init(struct cx25821_dev *dev)
    649{
    650	u32 value = 0, tmp = 0;
    651	int ret_val = 0;
    652	int i = 0;
    653
    654	/* disable Auto source selection on all video decoders */
    655	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
    656	value &= 0xFFFFF0FF;
    657	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
    658
    659	if (ret_val < 0)
    660		goto error;
    661
    662	/* Turn off Master source switch enable */
    663	value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
    664	value &= 0xFFFFFFDF;
    665	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
    666
    667	if (ret_val < 0)
    668		goto error;
    669
    670	/*
    671	 * FIXME: due to a coding bug the duration was always 0. It's
    672	 * likely that it really should be something else, but due to the
    673	 * lack of documentation I have no idea what it should be. For
    674	 * now just fill in 0 as the duration.
    675	 */
    676	for (i = 0; i < dev->_max_num_decoders; i++)
    677		medusa_set_decoderduration(dev, i, 0);
    678
    679	/* Select monitor as DENC A input, power up the DAC */
    680	value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
    681	value &= 0xFF70FF70;
    682	value |= 0x00090008;	/* set en_active */
    683	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
    684
    685	if (ret_val < 0)
    686		goto error;
    687
    688	/* enable input is VIP/656 */
    689	value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
    690	value |= 0x00040100;	/* enable VIP */
    691	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
    692
    693	if (ret_val < 0)
    694		goto error;
    695
    696	/* select AFE clock to output mode */
    697	value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
    698	value &= 0x83FFFFFF;
    699	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
    700			value | 0x10000000);
    701
    702	if (ret_val < 0)
    703		goto error;
    704
    705	/* Turn on all of the data out and control output pins. */
    706	value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
    707	value &= 0xFEF0FE00;
    708	if (dev->_max_num_decoders == MAX_DECODERS) {
    709		/*
    710		 * Note: The octal board does not support control pins(bit16-19)
    711		 * These bits are ignored in the octal board.
    712		 *
    713		 * disable VDEC A-C port, default to Mobilygen Interface
    714		 */
    715		value |= 0x010001F8;
    716	} else {
    717		/* disable VDEC A-C port, default to Mobilygen Interface */
    718		value |= 0x010F0108;
    719	}
    720
    721	value |= 7;
    722	ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
    723
    724	if (ret_val < 0)
    725		goto error;
    726
    727	ret_val = medusa_set_videostandard(dev);
    728
    729error:
    730	return ret_val;
    731}