WIP FPC-III support
[linux/fpc-iii.git] / drivers / media / pci / cx25821 / cx25821-medusa-video.c
blobf0a1ac77f048538c0dafbf43b71697be4721f3bd
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Driver for the Conexant CX25821 PCIe bridge
5 * Copyright (C) 2009 Conexant Systems Inc.
6 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
7 */
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include "cx25821.h"
12 #include "cx25821-medusa-video.h"
13 #include "cx25821-biffuncs.h"
16 * medusa_enable_bluefield_output()
18 * Enable the generation of blue filed output if no video
21 static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
22 int enable)
24 u32 value = 0;
25 u32 tmp = 0;
26 int out_ctrl = OUT_CTRL1;
27 int out_ctrl_ns = OUT_CTRL_NS;
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;
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);
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);
76 static int medusa_initialize_ntsc(struct cx25821_dev *dev)
78 int ret_val = 0;
79 int i = 0;
80 u32 value = 0;
81 u32 tmp = 0;
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);
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);
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);
108 /* chroma subcarrier step size */
109 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
110 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
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);
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);
129 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
130 * when the input switching rate < 16 fields
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);
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);
147 /* Enable the generation of blue field output if no video */
148 medusa_enable_bluefield_output(dev, i, 1);
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);
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);
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);
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);
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);
190 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
191 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
193 /* Subcarrier Increment */
194 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
195 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
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);
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);
209 return ret_val;
212 static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
214 int ret_val = -1;
215 u32 value = 0, tmp = 0;
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);
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);
232 /* set comb 2D blend */
233 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
234 COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
236 /* COMB MISC CONTROL */
237 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
238 COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
240 return ret_val;
243 static int medusa_initialize_pal(struct cx25821_dev *dev)
245 int ret_val = 0;
246 int i = 0;
247 u32 value = 0;
248 u32 tmp = 0;
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);
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);
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);
276 /* chroma subcarrier step size */
277 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
278 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
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);
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);
297 * clear VPRES_VERT_EN bit, fixes the chroma run away problem
298 * when the input switching rate < 16 fields
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);
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);
315 medusa_PALCombInit(dev, i);
317 /* Enable the generation of blue field output if no video */
318 medusa_enable_bluefield_output(dev, i, 1);
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);
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);
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);
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);
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);
361 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
362 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
364 /* Subcarrier Increment */
365 ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
366 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
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);
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);
380 return ret_val;
383 int medusa_set_videostandard(struct cx25821_dev *dev)
385 int status = 0;
386 u32 value = 0, tmp = 0;
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);
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);
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);
403 return status;
406 void medusa_set_resolution(struct cx25821_dev *dev, int width,
407 int decoder_select)
409 int decoder = 0;
410 int decoder_count = 0;
411 u32 hscale = 0x0;
412 u32 vscale = 0x0;
413 const int MAX_WIDTH = 720;
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;
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;
430 switch (width) {
431 case 320:
432 hscale = 0x13E34B;
433 vscale = 0x0;
434 break;
436 case 352:
437 hscale = 0x10A273;
438 vscale = 0x0;
439 break;
441 case 176:
442 hscale = 0x3115B2;
443 vscale = 0x1E00;
444 break;
446 case 160:
447 hscale = 0x378D84;
448 vscale = 0x1E00;
449 break;
451 default: /* 720 */
452 hscale = 0x0;
453 vscale = 0x0;
454 break;
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);
466 static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
467 int duration)
469 u32 fld_cnt = 0;
470 u32 tmp = 0;
471 u32 disp_cnt_reg = DISP_AB_CNT;
473 /* no support */
474 if (decoder < VDEC_A || decoder > VDEC_H) {
475 return;
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;
495 /* update hardware */
496 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
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;
506 cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
509 /* Map to Medusa register setting */
510 static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
511 int *dstVal)
513 int numerator;
514 int denominator;
515 int quotient;
517 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
518 return -1;
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.
526 numerator = (srcVal - srcMin) * (dstMax - dstMin);
527 denominator = srcMax - srcMin;
528 quotient = numerator / denominator;
530 if (2 * (numerator % denominator) >= denominator)
531 quotient++;
533 *dstVal = quotient + dstMin;
535 return 0;
538 static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
540 unsigned char temp;
542 if (numeric >= 0)
543 return numeric;
544 else {
545 temp = ~(abs(numeric) & 0xFF);
546 temp += 1;
547 return temp;
551 int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
553 int ret_val = 0;
554 int value = 0;
555 u32 val = 0, tmp = 0;
557 if ((brightness > VIDEO_PROCAMP_MAX) ||
558 (brightness < VIDEO_PROCAMP_MIN)) {
559 return -1;
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;
572 int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
574 int ret_val = 0;
575 int value = 0;
576 u32 val = 0, tmp = 0;
578 if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
579 return -1;
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);
590 return ret_val;
593 int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
595 int ret_val = 0;
596 int value = 0;
597 u32 val = 0, tmp = 0;
599 if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
600 return -1;
603 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
604 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
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;
611 ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
612 VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
614 return ret_val;
617 int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
619 int ret_val = 0;
620 int value = 0;
621 u32 val = 0, tmp = 0;
623 if ((saturation > VIDEO_PROCAMP_MAX) ||
624 (saturation < VIDEO_PROCAMP_MIN)) {
625 return -1;
628 ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
629 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
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);
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);
643 return ret_val;
646 /* Program the display sequence and monitor output. */
648 int medusa_video_init(struct cx25821_dev *dev)
650 u32 value = 0, tmp = 0;
651 int ret_val = 0;
652 int i = 0;
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);
659 if (ret_val < 0)
660 goto error;
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);
667 if (ret_val < 0)
668 goto error;
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.
676 for (i = 0; i < dev->_max_num_decoders; i++)
677 medusa_set_decoderduration(dev, i, 0);
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);
685 if (ret_val < 0)
686 goto error;
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);
693 if (ret_val < 0)
694 goto error;
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);
702 if (ret_val < 0)
703 goto error;
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) {
710 * Note: The octal board does not support control pins(bit16-19)
711 * These bits are ignored in the octal board.
713 * disable VDEC A-C port, default to Mobilygen Interface
715 value |= 0x010001F8;
716 } else {
717 /* disable VDEC A-C port, default to Mobilygen Interface */
718 value |= 0x010F0108;
721 value |= 7;
722 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
724 if (ret_val < 0)
725 goto error;
727 ret_val = medusa_set_videostandard(dev);
729 error:
730 return ret_val;