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