root/drivers/media/pci/cx25821/cx25821-medusa-video.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. medusa_enable_bluefield_output
  2. medusa_initialize_ntsc
  3. medusa_PALCombInit
  4. medusa_initialize_pal
  5. medusa_set_videostandard
  6. medusa_set_resolution
  7. medusa_set_decoderduration
  8. mapM
  9. convert_to_twos
  10. medusa_set_brightness
  11. medusa_set_contrast
  12. medusa_set_hue
  13. medusa_set_saturation
  14. medusa_video_init

   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  */
  21 static 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 
  76 static 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 
 212 static 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 
 243 static 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 
 383 int 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 
 406 void 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 
 466 static 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 */
 510 static 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 
 538 static 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 
 551 int 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 
 572 int 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 
 593 int 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 
 617 int 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 
 648 int 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 
 729 error:
 730         return ret_val;
 731 }

/* [<][>][^][v][top][bottom][index][help] */