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