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