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