linux/drivers/media/pci/cx25821/cx25821-medusa-video.c
<<
>>
Prefs
   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}
 732