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