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