Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for the Conexant CX25821 PCIe bridge
0004  *
0005  *  Copyright (C) 2009 Conexant Systems Inc.
0006  *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include "cx25821.h"
0012 #include "cx25821-medusa-video.h"
0013 #include "cx25821-biffuncs.h"
0014 
0015 /*
0016  * medusa_enable_bluefield_output()
0017  *
0018  * Enable the generation of blue filed output if no video
0019  *
0020  */
0021 static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
0022                        int enable)
0023 {
0024     u32 value = 0;
0025     u32 tmp = 0;
0026     int out_ctrl = OUT_CTRL1;
0027     int out_ctrl_ns = OUT_CTRL_NS;
0028 
0029     switch (channel) {
0030     default:
0031     case VDEC_A:
0032         break;
0033     case VDEC_B:
0034         out_ctrl = VDEC_B_OUT_CTRL1;
0035         out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
0036         break;
0037     case VDEC_C:
0038         out_ctrl = VDEC_C_OUT_CTRL1;
0039         out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
0040         break;
0041     case VDEC_D:
0042         out_ctrl = VDEC_D_OUT_CTRL1;
0043         out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
0044         break;
0045     case VDEC_E:
0046         out_ctrl = VDEC_E_OUT_CTRL1;
0047         out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
0048         return;
0049     case VDEC_F:
0050         out_ctrl = VDEC_F_OUT_CTRL1;
0051         out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
0052         return;
0053     case VDEC_G:
0054         out_ctrl = VDEC_G_OUT_CTRL1;
0055         out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
0056         return;
0057     case VDEC_H:
0058         out_ctrl = VDEC_H_OUT_CTRL1;
0059         out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
0060         return;
0061     }
0062 
0063     value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
0064     value &= 0xFFFFFF7F;    /* clear BLUE_FIELD_EN */
0065     if (enable)
0066         value |= 0x00000080;    /* set BLUE_FIELD_EN */
0067     cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
0068 
0069     value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
0070     value &= 0xFFFFFF7F;
0071     if (enable)
0072         value |= 0x00000080;    /* set BLUE_FIELD_EN */
0073     cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
0074 }
0075 
0076 static int medusa_initialize_ntsc(struct cx25821_dev *dev)
0077 {
0078     int ret_val = 0;
0079     int i = 0;
0080     u32 value = 0;
0081     u32 tmp = 0;
0082 
0083     for (i = 0; i < MAX_DECODERS; i++) {
0084         /* set video format NTSC-M */
0085         value = cx25821_i2c_read(&dev->i2c_bus[0],
0086                 MODE_CTRL + (0x200 * i), &tmp);
0087         value &= 0xFFFFFFF0;
0088         /* enable the fast locking mode bit[16] */
0089         value |= 0x10001;
0090         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0091                 MODE_CTRL + (0x200 * i), value);
0092 
0093         /* resolution NTSC 720x480 */
0094         value = cx25821_i2c_read(&dev->i2c_bus[0],
0095                 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
0096         value &= 0x00C00C00;
0097         value |= 0x612D0074;
0098         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0099                 HORIZ_TIM_CTRL + (0x200 * i), value);
0100 
0101         value = cx25821_i2c_read(&dev->i2c_bus[0],
0102                 VERT_TIM_CTRL + (0x200 * i), &tmp);
0103         value &= 0x00C00C00;
0104         value |= 0x1C1E001A;    /* vblank_cnt + 2 to get camera ID */
0105         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0106                 VERT_TIM_CTRL + (0x200 * i), value);
0107 
0108         /* chroma subcarrier step size */
0109         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0110                 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
0111 
0112         /* enable VIP optional active */
0113         value = cx25821_i2c_read(&dev->i2c_bus[0],
0114                 OUT_CTRL_NS + (0x200 * i), &tmp);
0115         value &= 0xFFFBFFFF;
0116         value |= 0x00040000;
0117         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0118                 OUT_CTRL_NS + (0x200 * i), value);
0119 
0120         /* enable VIP optional active (VIP_OPT_AL) for direct output. */
0121         value = cx25821_i2c_read(&dev->i2c_bus[0],
0122                 OUT_CTRL1 + (0x200 * i), &tmp);
0123         value &= 0xFFFBFFFF;
0124         value |= 0x00040000;
0125         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0126                 OUT_CTRL1 + (0x200 * i), value);
0127 
0128         /*
0129          * clear VPRES_VERT_EN bit, fixes the chroma run away problem
0130          * when the input switching rate < 16 fields
0131         */
0132         value = cx25821_i2c_read(&dev->i2c_bus[0],
0133                 MISC_TIM_CTRL + (0x200 * i), &tmp);
0134         /* disable special play detection */
0135         value = setBitAtPos(value, 14);
0136         value = clearBitAtPos(value, 15);
0137         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0138                 MISC_TIM_CTRL + (0x200 * i), value);
0139 
0140         /* set vbi_gate_en to 0 */
0141         value = cx25821_i2c_read(&dev->i2c_bus[0],
0142                 DFE_CTRL1 + (0x200 * i), &tmp);
0143         value = clearBitAtPos(value, 29);
0144         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0145                 DFE_CTRL1 + (0x200 * i), value);
0146 
0147         /* Enable the generation of blue field output if no video */
0148         medusa_enable_bluefield_output(dev, i, 1);
0149     }
0150 
0151     for (i = 0; i < MAX_ENCODERS; i++) {
0152         /* NTSC hclock */
0153         value = cx25821_i2c_read(&dev->i2c_bus[0],
0154                 DENC_A_REG_1 + (0x100 * i), &tmp);
0155         value &= 0xF000FC00;
0156         value |= 0x06B402D0;
0157         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0158                 DENC_A_REG_1 + (0x100 * i), value);
0159 
0160         /* burst begin and burst end */
0161         value = cx25821_i2c_read(&dev->i2c_bus[0],
0162                 DENC_A_REG_2 + (0x100 * i), &tmp);
0163         value &= 0xFF000000;
0164         value |= 0x007E9054;
0165         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0166                 DENC_A_REG_2 + (0x100 * i), value);
0167 
0168         value = cx25821_i2c_read(&dev->i2c_bus[0],
0169                 DENC_A_REG_3 + (0x100 * i), &tmp);
0170         value &= 0xFC00FE00;
0171         value |= 0x00EC00F0;
0172         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0173                 DENC_A_REG_3 + (0x100 * i), value);
0174 
0175         /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */
0176         value = cx25821_i2c_read(&dev->i2c_bus[0],
0177                 DENC_A_REG_4 + (0x100 * i), &tmp);
0178         value &= 0x00FCFFFF;
0179         value |= 0x13020000;
0180         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0181                 DENC_A_REG_4 + (0x100 * i), value);
0182 
0183         value = cx25821_i2c_read(&dev->i2c_bus[0],
0184                 DENC_A_REG_5 + (0x100 * i), &tmp);
0185         value &= 0xFFFF0000;
0186         value |= 0x0000E575;
0187         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0188                 DENC_A_REG_5 + (0x100 * i), value);
0189 
0190         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0191                 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
0192 
0193         /* Subcarrier Increment */
0194         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0195                 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
0196     }
0197 
0198     /* set picture resolutions */
0199     /* 0 - 720 */
0200     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
0201     /* 0 - 480 */
0202     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
0203 
0204     /* set Bypass input format to NTSC 525 lines */
0205     value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
0206     value |= 0x00080200;
0207     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
0208 
0209     return ret_val;
0210 }
0211 
0212 static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
0213 {
0214     int ret_val = -1;
0215     u32 value = 0, tmp = 0;
0216 
0217     /* Setup for 2D threshold */
0218     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0219             COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861);
0220     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0221             COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861);
0222     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0223             COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023);
0224 
0225     /* Setup flat chroma and luma thresholds */
0226     value = cx25821_i2c_read(&dev->i2c_bus[0],
0227             COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
0228     value &= 0x06230000;
0229     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0230             COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
0231 
0232     /* set comb 2D blend */
0233     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0234             COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F);
0235 
0236     /* COMB MISC CONTROL */
0237     ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0238             COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F);
0239 
0240     return ret_val;
0241 }
0242 
0243 static int medusa_initialize_pal(struct cx25821_dev *dev)
0244 {
0245     int ret_val = 0;
0246     int i = 0;
0247     u32 value = 0;
0248     u32 tmp = 0;
0249 
0250     for (i = 0; i < MAX_DECODERS; i++) {
0251         /* set video format PAL-BDGHI */
0252         value = cx25821_i2c_read(&dev->i2c_bus[0],
0253                 MODE_CTRL + (0x200 * i), &tmp);
0254         value &= 0xFFFFFFF0;
0255         /* enable the fast locking mode bit[16] */
0256         value |= 0x10004;
0257         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0258                 MODE_CTRL + (0x200 * i), value);
0259 
0260         /* resolution PAL 720x576 */
0261         value = cx25821_i2c_read(&dev->i2c_bus[0],
0262                 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
0263         value &= 0x00C00C00;
0264         value |= 0x632D007D;
0265         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0266                 HORIZ_TIM_CTRL + (0x200 * i), value);
0267 
0268         /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */
0269         value = cx25821_i2c_read(&dev->i2c_bus[0],
0270                 VERT_TIM_CTRL + (0x200 * i), &tmp);
0271         value &= 0x00C00C00;
0272         value |= 0x28240026;    /* vblank_cnt + 2 to get camera ID */
0273         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0274                 VERT_TIM_CTRL + (0x200 * i), value);
0275 
0276         /* chroma subcarrier step size */
0277         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0278                 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
0279 
0280         /* enable VIP optional active */
0281         value = cx25821_i2c_read(&dev->i2c_bus[0],
0282                 OUT_CTRL_NS + (0x200 * i), &tmp);
0283         value &= 0xFFFBFFFF;
0284         value |= 0x00040000;
0285         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0286                 OUT_CTRL_NS + (0x200 * i), value);
0287 
0288         /* enable VIP optional active (VIP_OPT_AL) for direct output. */
0289         value = cx25821_i2c_read(&dev->i2c_bus[0],
0290                 OUT_CTRL1 + (0x200 * i), &tmp);
0291         value &= 0xFFFBFFFF;
0292         value |= 0x00040000;
0293         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0294                 OUT_CTRL1 + (0x200 * i), value);
0295 
0296         /*
0297          * clear VPRES_VERT_EN bit, fixes the chroma run away problem
0298          * when the input switching rate < 16 fields
0299          */
0300         value = cx25821_i2c_read(&dev->i2c_bus[0],
0301                 MISC_TIM_CTRL + (0x200 * i), &tmp);
0302         /* disable special play detection */
0303         value = setBitAtPos(value, 14);
0304         value = clearBitAtPos(value, 15);
0305         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0306                 MISC_TIM_CTRL + (0x200 * i), value);
0307 
0308         /* set vbi_gate_en to 0 */
0309         value = cx25821_i2c_read(&dev->i2c_bus[0],
0310                 DFE_CTRL1 + (0x200 * i), &tmp);
0311         value = clearBitAtPos(value, 29);
0312         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0313                 DFE_CTRL1 + (0x200 * i), value);
0314 
0315         medusa_PALCombInit(dev, i);
0316 
0317         /* Enable the generation of blue field output if no video */
0318         medusa_enable_bluefield_output(dev, i, 1);
0319     }
0320 
0321     for (i = 0; i < MAX_ENCODERS; i++) {
0322         /* PAL hclock */
0323         value = cx25821_i2c_read(&dev->i2c_bus[0],
0324                 DENC_A_REG_1 + (0x100 * i), &tmp);
0325         value &= 0xF000FC00;
0326         value |= 0x06C002D0;
0327         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0328                 DENC_A_REG_1 + (0x100 * i), value);
0329 
0330         /* burst begin and burst end */
0331         value = cx25821_i2c_read(&dev->i2c_bus[0],
0332                 DENC_A_REG_2 + (0x100 * i), &tmp);
0333         value &= 0xFF000000;
0334         value |= 0x007E9754;
0335         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0336                 DENC_A_REG_2 + (0x100 * i), value);
0337 
0338         /* hblank and vactive */
0339         value = cx25821_i2c_read(&dev->i2c_bus[0],
0340                 DENC_A_REG_3 + (0x100 * i), &tmp);
0341         value &= 0xFC00FE00;
0342         value |= 0x00FC0120;
0343         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0344                 DENC_A_REG_3 + (0x100 * i), value);
0345 
0346         /* set PAL vblank, phase alternation, 0 IRE pedestal */
0347         value = cx25821_i2c_read(&dev->i2c_bus[0],
0348                 DENC_A_REG_4 + (0x100 * i), &tmp);
0349         value &= 0x00FCFFFF;
0350         value |= 0x14010000;
0351         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0352                 DENC_A_REG_4 + (0x100 * i), value);
0353 
0354         value = cx25821_i2c_read(&dev->i2c_bus[0],
0355                 DENC_A_REG_5 + (0x100 * i), &tmp);
0356         value &= 0xFFFF0000;
0357         value |= 0x0000F078;
0358         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0359                 DENC_A_REG_5 + (0x100 * i), value);
0360 
0361         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0362                 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
0363 
0364         /* Subcarrier Increment */
0365         ret_val = cx25821_i2c_write(&dev->i2c_bus[0],
0366                 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
0367     }
0368 
0369     /* set picture resolutions */
0370     /* 0 - 720 */
0371     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0);
0372     /* 0 - 576 */
0373     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0);
0374 
0375     /* set Bypass input format to PAL 625 lines */
0376     value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
0377     value &= 0xFFF7FDFF;
0378     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
0379 
0380     return ret_val;
0381 }
0382 
0383 int medusa_set_videostandard(struct cx25821_dev *dev)
0384 {
0385     int status = 0;
0386     u32 value = 0, tmp = 0;
0387 
0388     if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
0389         status = medusa_initialize_pal(dev);
0390     else
0391         status = medusa_initialize_ntsc(dev);
0392 
0393     /* Enable DENC_A output */
0394     value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
0395     value = setBitAtPos(value, 4);
0396     status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
0397 
0398     /* Enable DENC_B output */
0399     value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
0400     value = setBitAtPos(value, 4);
0401     status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
0402 
0403     return status;
0404 }
0405 
0406 void medusa_set_resolution(struct cx25821_dev *dev, int width,
0407                int decoder_select)
0408 {
0409     int decoder = 0;
0410     int decoder_count = 0;
0411     u32 hscale = 0x0;
0412     u32 vscale = 0x0;
0413     const int MAX_WIDTH = 720;
0414 
0415     /* validate the width */
0416     if (width > MAX_WIDTH) {
0417         pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n",
0418             __func__, width, MAX_WIDTH);
0419         width = MAX_WIDTH;
0420     }
0421 
0422     if (decoder_select <= 7 && decoder_select >= 0) {
0423         decoder = decoder_select;
0424         decoder_count = decoder_select + 1;
0425     } else {
0426         decoder = 0;
0427         decoder_count = dev->_max_num_decoders;
0428     }
0429 
0430     switch (width) {
0431     case 320:
0432         hscale = 0x13E34B;
0433         vscale = 0x0;
0434         break;
0435 
0436     case 352:
0437         hscale = 0x10A273;
0438         vscale = 0x0;
0439         break;
0440 
0441     case 176:
0442         hscale = 0x3115B2;
0443         vscale = 0x1E00;
0444         break;
0445 
0446     case 160:
0447         hscale = 0x378D84;
0448         vscale = 0x1E00;
0449         break;
0450 
0451     default:        /* 720 */
0452         hscale = 0x0;
0453         vscale = 0x0;
0454         break;
0455     }
0456 
0457     for (; decoder < decoder_count; decoder++) {
0458         /* write scaling values for each decoder */
0459         cx25821_i2c_write(&dev->i2c_bus[0],
0460                 HSCALE_CTRL + (0x200 * decoder), hscale);
0461         cx25821_i2c_write(&dev->i2c_bus[0],
0462                 VSCALE_CTRL + (0x200 * decoder), vscale);
0463     }
0464 }
0465 
0466 static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
0467                        int duration)
0468 {
0469     u32 fld_cnt = 0;
0470     u32 tmp = 0;
0471     u32 disp_cnt_reg = DISP_AB_CNT;
0472 
0473     /* no support */
0474     if (decoder < VDEC_A || decoder > VDEC_H) {
0475         return;
0476     }
0477 
0478     switch (decoder) {
0479     default:
0480         break;
0481     case VDEC_C:
0482     case VDEC_D:
0483         disp_cnt_reg = DISP_CD_CNT;
0484         break;
0485     case VDEC_E:
0486     case VDEC_F:
0487         disp_cnt_reg = DISP_EF_CNT;
0488         break;
0489     case VDEC_G:
0490     case VDEC_H:
0491         disp_cnt_reg = DISP_GH_CNT;
0492         break;
0493     }
0494 
0495     /* update hardware */
0496     fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
0497 
0498     if (!(decoder % 2)) {   /* EVEN decoder */
0499         fld_cnt &= 0xFFFF0000;
0500         fld_cnt |= duration;
0501     } else {
0502         fld_cnt &= 0x0000FFFF;
0503         fld_cnt |= ((u32) duration) << 16;
0504     }
0505 
0506     cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
0507 }
0508 
0509 /* Map to Medusa register setting */
0510 static int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax,
0511         int *dstVal)
0512 {
0513     int numerator;
0514     int denominator;
0515     int quotient;
0516 
0517     if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax))
0518         return -1;
0519     /*
0520      * This is the overall expression used:
0521      * *dstVal =
0522      *   (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
0523      * but we need to account for rounding so below we use the modulus
0524      * operator to find the remainder and increment if necessary.
0525      */
0526     numerator = (srcVal - srcMin) * (dstMax - dstMin);
0527     denominator = srcMax - srcMin;
0528     quotient = numerator / denominator;
0529 
0530     if (2 * (numerator % denominator) >= denominator)
0531         quotient++;
0532 
0533     *dstVal = quotient + dstMin;
0534 
0535     return 0;
0536 }
0537 
0538 static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
0539 {
0540     unsigned char temp;
0541 
0542     if (numeric >= 0)
0543         return numeric;
0544     else {
0545         temp = ~(abs(numeric) & 0xFF);
0546         temp += 1;
0547         return temp;
0548     }
0549 }
0550 
0551 int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
0552 {
0553     int ret_val = 0;
0554     int value = 0;
0555     u32 val = 0, tmp = 0;
0556 
0557     if ((brightness > VIDEO_PROCAMP_MAX) ||
0558         (brightness < VIDEO_PROCAMP_MIN)) {
0559         return -1;
0560     }
0561     ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
0562             SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
0563     value = convert_to_twos(value, 8);
0564     val = cx25821_i2c_read(&dev->i2c_bus[0],
0565             VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
0566     val &= 0xFFFFFF00;
0567     ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
0568             VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value);
0569     return ret_val;
0570 }
0571 
0572 int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
0573 {
0574     int ret_val = 0;
0575     int value = 0;
0576     u32 val = 0, tmp = 0;
0577 
0578     if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
0579         return -1;
0580     }
0581 
0582     ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
0583             UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
0584     val = cx25821_i2c_read(&dev->i2c_bus[0],
0585             VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
0586     val &= 0xFFFFFF00;
0587     ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
0588             VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value);
0589 
0590     return ret_val;
0591 }
0592 
0593 int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
0594 {
0595     int ret_val = 0;
0596     int value = 0;
0597     u32 val = 0, tmp = 0;
0598 
0599     if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
0600         return -1;
0601     }
0602 
0603     ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue,
0604             SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
0605 
0606     value = convert_to_twos(value, 8);
0607     val = cx25821_i2c_read(&dev->i2c_bus[0],
0608             VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
0609     val &= 0xFFFFFF00;
0610 
0611     ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
0612             VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
0613 
0614     return ret_val;
0615 }
0616 
0617 int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
0618 {
0619     int ret_val = 0;
0620     int value = 0;
0621     u32 val = 0, tmp = 0;
0622 
0623     if ((saturation > VIDEO_PROCAMP_MAX) ||
0624         (saturation < VIDEO_PROCAMP_MIN)) {
0625         return -1;
0626     }
0627 
0628     ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
0629             UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
0630 
0631     val = cx25821_i2c_read(&dev->i2c_bus[0],
0632             VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
0633     val &= 0xFFFFFF00;
0634     ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
0635             VDEC_A_USAT_CTRL + (0x200 * decoder), val | value);
0636 
0637     val = cx25821_i2c_read(&dev->i2c_bus[0],
0638             VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
0639     val &= 0xFFFFFF00;
0640     ret_val |= cx25821_i2c_write(&dev->i2c_bus[0],
0641             VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value);
0642 
0643     return ret_val;
0644 }
0645 
0646 /* Program the display sequence and monitor output. */
0647 
0648 int medusa_video_init(struct cx25821_dev *dev)
0649 {
0650     u32 value = 0, tmp = 0;
0651     int ret_val = 0;
0652     int i = 0;
0653 
0654     /* disable Auto source selection on all video decoders */
0655     value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
0656     value &= 0xFFFFF0FF;
0657     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
0658 
0659     if (ret_val < 0)
0660         goto error;
0661 
0662     /* Turn off Master source switch enable */
0663     value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
0664     value &= 0xFFFFFFDF;
0665     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
0666 
0667     if (ret_val < 0)
0668         goto error;
0669 
0670     /*
0671      * FIXME: due to a coding bug the duration was always 0. It's
0672      * likely that it really should be something else, but due to the
0673      * lack of documentation I have no idea what it should be. For
0674      * now just fill in 0 as the duration.
0675      */
0676     for (i = 0; i < dev->_max_num_decoders; i++)
0677         medusa_set_decoderduration(dev, i, 0);
0678 
0679     /* Select monitor as DENC A input, power up the DAC */
0680     value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
0681     value &= 0xFF70FF70;
0682     value |= 0x00090008;    /* set en_active */
0683     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
0684 
0685     if (ret_val < 0)
0686         goto error;
0687 
0688     /* enable input is VIP/656 */
0689     value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
0690     value |= 0x00040100;    /* enable VIP */
0691     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
0692 
0693     if (ret_val < 0)
0694         goto error;
0695 
0696     /* select AFE clock to output mode */
0697     value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
0698     value &= 0x83FFFFFF;
0699     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
0700             value | 0x10000000);
0701 
0702     if (ret_val < 0)
0703         goto error;
0704 
0705     /* Turn on all of the data out and control output pins. */
0706     value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
0707     value &= 0xFEF0FE00;
0708     if (dev->_max_num_decoders == MAX_DECODERS) {
0709         /*
0710          * Note: The octal board does not support control pins(bit16-19)
0711          * These bits are ignored in the octal board.
0712          *
0713          * disable VDEC A-C port, default to Mobilygen Interface
0714          */
0715         value |= 0x010001F8;
0716     } else {
0717         /* disable VDEC A-C port, default to Mobilygen Interface */
0718         value |= 0x010F0108;
0719     }
0720 
0721     value |= 7;
0722     ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
0723 
0724     if (ret_val < 0)
0725         goto error;
0726 
0727     ret_val = medusa_set_videostandard(dev);
0728 
0729 error:
0730     return ret_val;
0731 }