18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Driver for the Conexant CX25821 PCIe bridge 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2009 Conexant Systems Inc. 68c2ecf20Sopenharmony_ci * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include "cx25821.h" 128c2ecf20Sopenharmony_ci#include "cx25821-medusa-video.h" 138c2ecf20Sopenharmony_ci#include "cx25821-biffuncs.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * medusa_enable_bluefield_output() 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * Enable the generation of blue filed output if no video 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_cistatic void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel, 228c2ecf20Sopenharmony_ci int enable) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci u32 value = 0; 258c2ecf20Sopenharmony_ci u32 tmp = 0; 268c2ecf20Sopenharmony_ci int out_ctrl = OUT_CTRL1; 278c2ecf20Sopenharmony_ci int out_ctrl_ns = OUT_CTRL_NS; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci switch (channel) { 308c2ecf20Sopenharmony_ci default: 318c2ecf20Sopenharmony_ci case VDEC_A: 328c2ecf20Sopenharmony_ci break; 338c2ecf20Sopenharmony_ci case VDEC_B: 348c2ecf20Sopenharmony_ci out_ctrl = VDEC_B_OUT_CTRL1; 358c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_B_OUT_CTRL_NS; 368c2ecf20Sopenharmony_ci break; 378c2ecf20Sopenharmony_ci case VDEC_C: 388c2ecf20Sopenharmony_ci out_ctrl = VDEC_C_OUT_CTRL1; 398c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_C_OUT_CTRL_NS; 408c2ecf20Sopenharmony_ci break; 418c2ecf20Sopenharmony_ci case VDEC_D: 428c2ecf20Sopenharmony_ci out_ctrl = VDEC_D_OUT_CTRL1; 438c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_D_OUT_CTRL_NS; 448c2ecf20Sopenharmony_ci break; 458c2ecf20Sopenharmony_ci case VDEC_E: 468c2ecf20Sopenharmony_ci out_ctrl = VDEC_E_OUT_CTRL1; 478c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_E_OUT_CTRL_NS; 488c2ecf20Sopenharmony_ci return; 498c2ecf20Sopenharmony_ci case VDEC_F: 508c2ecf20Sopenharmony_ci out_ctrl = VDEC_F_OUT_CTRL1; 518c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_F_OUT_CTRL_NS; 528c2ecf20Sopenharmony_ci return; 538c2ecf20Sopenharmony_ci case VDEC_G: 548c2ecf20Sopenharmony_ci out_ctrl = VDEC_G_OUT_CTRL1; 558c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_G_OUT_CTRL_NS; 568c2ecf20Sopenharmony_ci return; 578c2ecf20Sopenharmony_ci case VDEC_H: 588c2ecf20Sopenharmony_ci out_ctrl = VDEC_H_OUT_CTRL1; 598c2ecf20Sopenharmony_ci out_ctrl_ns = VDEC_H_OUT_CTRL_NS; 608c2ecf20Sopenharmony_ci return; 618c2ecf20Sopenharmony_ci } 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp); 648c2ecf20Sopenharmony_ci value &= 0xFFFFFF7F; /* clear BLUE_FIELD_EN */ 658c2ecf20Sopenharmony_ci if (enable) 668c2ecf20Sopenharmony_ci value |= 0x00000080; /* set BLUE_FIELD_EN */ 678c2ecf20Sopenharmony_ci cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp); 708c2ecf20Sopenharmony_ci value &= 0xFFFFFF7F; 718c2ecf20Sopenharmony_ci if (enable) 728c2ecf20Sopenharmony_ci value |= 0x00000080; /* set BLUE_FIELD_EN */ 738c2ecf20Sopenharmony_ci cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_cistatic int medusa_initialize_ntsc(struct cx25821_dev *dev) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci int ret_val = 0; 798c2ecf20Sopenharmony_ci int i = 0; 808c2ecf20Sopenharmony_ci u32 value = 0; 818c2ecf20Sopenharmony_ci u32 tmp = 0; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DECODERS; i++) { 848c2ecf20Sopenharmony_ci /* set video format NTSC-M */ 858c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 868c2ecf20Sopenharmony_ci MODE_CTRL + (0x200 * i), &tmp); 878c2ecf20Sopenharmony_ci value &= 0xFFFFFFF0; 888c2ecf20Sopenharmony_ci /* enable the fast locking mode bit[16] */ 898c2ecf20Sopenharmony_ci value |= 0x10001; 908c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 918c2ecf20Sopenharmony_ci MODE_CTRL + (0x200 * i), value); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* resolution NTSC 720x480 */ 948c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 958c2ecf20Sopenharmony_ci HORIZ_TIM_CTRL + (0x200 * i), &tmp); 968c2ecf20Sopenharmony_ci value &= 0x00C00C00; 978c2ecf20Sopenharmony_ci value |= 0x612D0074; 988c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 998c2ecf20Sopenharmony_ci HORIZ_TIM_CTRL + (0x200 * i), value); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1028c2ecf20Sopenharmony_ci VERT_TIM_CTRL + (0x200 * i), &tmp); 1038c2ecf20Sopenharmony_ci value &= 0x00C00C00; 1048c2ecf20Sopenharmony_ci value |= 0x1C1E001A; /* vblank_cnt + 2 to get camera ID */ 1058c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1068c2ecf20Sopenharmony_ci VERT_TIM_CTRL + (0x200 * i), value); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci /* chroma subcarrier step size */ 1098c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1108c2ecf20Sopenharmony_ci SC_STEP_SIZE + (0x200 * i), 0x43E00000); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci /* enable VIP optional active */ 1138c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1148c2ecf20Sopenharmony_ci OUT_CTRL_NS + (0x200 * i), &tmp); 1158c2ecf20Sopenharmony_ci value &= 0xFFFBFFFF; 1168c2ecf20Sopenharmony_ci value |= 0x00040000; 1178c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1188c2ecf20Sopenharmony_ci OUT_CTRL_NS + (0x200 * i), value); 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci /* enable VIP optional active (VIP_OPT_AL) for direct output. */ 1218c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1228c2ecf20Sopenharmony_ci OUT_CTRL1 + (0x200 * i), &tmp); 1238c2ecf20Sopenharmony_ci value &= 0xFFFBFFFF; 1248c2ecf20Sopenharmony_ci value |= 0x00040000; 1258c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1268c2ecf20Sopenharmony_ci OUT_CTRL1 + (0x200 * i), value); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci /* 1298c2ecf20Sopenharmony_ci * clear VPRES_VERT_EN bit, fixes the chroma run away problem 1308c2ecf20Sopenharmony_ci * when the input switching rate < 16 fields 1318c2ecf20Sopenharmony_ci */ 1328c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1338c2ecf20Sopenharmony_ci MISC_TIM_CTRL + (0x200 * i), &tmp); 1348c2ecf20Sopenharmony_ci /* disable special play detection */ 1358c2ecf20Sopenharmony_ci value = setBitAtPos(value, 14); 1368c2ecf20Sopenharmony_ci value = clearBitAtPos(value, 15); 1378c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1388c2ecf20Sopenharmony_ci MISC_TIM_CTRL + (0x200 * i), value); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci /* set vbi_gate_en to 0 */ 1418c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1428c2ecf20Sopenharmony_ci DFE_CTRL1 + (0x200 * i), &tmp); 1438c2ecf20Sopenharmony_ci value = clearBitAtPos(value, 29); 1448c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1458c2ecf20Sopenharmony_ci DFE_CTRL1 + (0x200 * i), value); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci /* Enable the generation of blue field output if no video */ 1488c2ecf20Sopenharmony_ci medusa_enable_bluefield_output(dev, i, 1); 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci for (i = 0; i < MAX_ENCODERS; i++) { 1528c2ecf20Sopenharmony_ci /* NTSC hclock */ 1538c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1548c2ecf20Sopenharmony_ci DENC_A_REG_1 + (0x100 * i), &tmp); 1558c2ecf20Sopenharmony_ci value &= 0xF000FC00; 1568c2ecf20Sopenharmony_ci value |= 0x06B402D0; 1578c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1588c2ecf20Sopenharmony_ci DENC_A_REG_1 + (0x100 * i), value); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci /* burst begin and burst end */ 1618c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1628c2ecf20Sopenharmony_ci DENC_A_REG_2 + (0x100 * i), &tmp); 1638c2ecf20Sopenharmony_ci value &= 0xFF000000; 1648c2ecf20Sopenharmony_ci value |= 0x007E9054; 1658c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1668c2ecf20Sopenharmony_ci DENC_A_REG_2 + (0x100 * i), value); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1698c2ecf20Sopenharmony_ci DENC_A_REG_3 + (0x100 * i), &tmp); 1708c2ecf20Sopenharmony_ci value &= 0xFC00FE00; 1718c2ecf20Sopenharmony_ci value |= 0x00EC00F0; 1728c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1738c2ecf20Sopenharmony_ci DENC_A_REG_3 + (0x100 * i), value); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci /* set NTSC vblank, no phase alternation, 7.5 IRE pedestal */ 1768c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1778c2ecf20Sopenharmony_ci DENC_A_REG_4 + (0x100 * i), &tmp); 1788c2ecf20Sopenharmony_ci value &= 0x00FCFFFF; 1798c2ecf20Sopenharmony_ci value |= 0x13020000; 1808c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1818c2ecf20Sopenharmony_ci DENC_A_REG_4 + (0x100 * i), value); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 1848c2ecf20Sopenharmony_ci DENC_A_REG_5 + (0x100 * i), &tmp); 1858c2ecf20Sopenharmony_ci value &= 0xFFFF0000; 1868c2ecf20Sopenharmony_ci value |= 0x0000E575; 1878c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1888c2ecf20Sopenharmony_ci DENC_A_REG_5 + (0x100 * i), value); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1918c2ecf20Sopenharmony_ci DENC_A_REG_6 + (0x100 * i), 0x009A89C1); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci /* Subcarrier Increment */ 1948c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 1958c2ecf20Sopenharmony_ci DENC_A_REG_7 + (0x100 * i), 0x21F07C1F); 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* set picture resolutions */ 1998c2ecf20Sopenharmony_ci /* 0 - 720 */ 2008c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); 2018c2ecf20Sopenharmony_ci /* 0 - 480 */ 2028c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* set Bypass input format to NTSC 525 lines */ 2058c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 2068c2ecf20Sopenharmony_ci value |= 0x00080200; 2078c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci return ret_val; 2108c2ecf20Sopenharmony_ci} 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic int medusa_PALCombInit(struct cx25821_dev *dev, int dec) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci int ret_val = -1; 2158c2ecf20Sopenharmony_ci u32 value = 0, tmp = 0; 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci /* Setup for 2D threshold */ 2188c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2198c2ecf20Sopenharmony_ci COMB_2D_HFS_CFG + (0x200 * dec), 0x20002861); 2208c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2218c2ecf20Sopenharmony_ci COMB_2D_HFD_CFG + (0x200 * dec), 0x20002861); 2228c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2238c2ecf20Sopenharmony_ci COMB_2D_LF_CFG + (0x200 * dec), 0x200A1023); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci /* Setup flat chroma and luma thresholds */ 2268c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2278c2ecf20Sopenharmony_ci COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp); 2288c2ecf20Sopenharmony_ci value &= 0x06230000; 2298c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2308c2ecf20Sopenharmony_ci COMB_FLAT_THRESH_CTRL + (0x200 * dec), value); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci /* set comb 2D blend */ 2338c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2348c2ecf20Sopenharmony_ci COMB_2D_BLEND + (0x200 * dec), 0x210F0F0F); 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci /* COMB MISC CONTROL */ 2378c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2388c2ecf20Sopenharmony_ci COMB_MISC_CTRL + (0x200 * dec), 0x41120A7F); 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_ci return ret_val; 2418c2ecf20Sopenharmony_ci} 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_cistatic int medusa_initialize_pal(struct cx25821_dev *dev) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci int ret_val = 0; 2468c2ecf20Sopenharmony_ci int i = 0; 2478c2ecf20Sopenharmony_ci u32 value = 0; 2488c2ecf20Sopenharmony_ci u32 tmp = 0; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci for (i = 0; i < MAX_DECODERS; i++) { 2518c2ecf20Sopenharmony_ci /* set video format PAL-BDGHI */ 2528c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2538c2ecf20Sopenharmony_ci MODE_CTRL + (0x200 * i), &tmp); 2548c2ecf20Sopenharmony_ci value &= 0xFFFFFFF0; 2558c2ecf20Sopenharmony_ci /* enable the fast locking mode bit[16] */ 2568c2ecf20Sopenharmony_ci value |= 0x10004; 2578c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2588c2ecf20Sopenharmony_ci MODE_CTRL + (0x200 * i), value); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci /* resolution PAL 720x576 */ 2618c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2628c2ecf20Sopenharmony_ci HORIZ_TIM_CTRL + (0x200 * i), &tmp); 2638c2ecf20Sopenharmony_ci value &= 0x00C00C00; 2648c2ecf20Sopenharmony_ci value |= 0x632D007D; 2658c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2668c2ecf20Sopenharmony_ci HORIZ_TIM_CTRL + (0x200 * i), value); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci /* vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24 */ 2698c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2708c2ecf20Sopenharmony_ci VERT_TIM_CTRL + (0x200 * i), &tmp); 2718c2ecf20Sopenharmony_ci value &= 0x00C00C00; 2728c2ecf20Sopenharmony_ci value |= 0x28240026; /* vblank_cnt + 2 to get camera ID */ 2738c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2748c2ecf20Sopenharmony_ci VERT_TIM_CTRL + (0x200 * i), value); 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* chroma subcarrier step size */ 2778c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2788c2ecf20Sopenharmony_ci SC_STEP_SIZE + (0x200 * i), 0x5411E2D0); 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci /* enable VIP optional active */ 2818c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2828c2ecf20Sopenharmony_ci OUT_CTRL_NS + (0x200 * i), &tmp); 2838c2ecf20Sopenharmony_ci value &= 0xFFFBFFFF; 2848c2ecf20Sopenharmony_ci value |= 0x00040000; 2858c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2868c2ecf20Sopenharmony_ci OUT_CTRL_NS + (0x200 * i), value); 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci /* enable VIP optional active (VIP_OPT_AL) for direct output. */ 2898c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 2908c2ecf20Sopenharmony_ci OUT_CTRL1 + (0x200 * i), &tmp); 2918c2ecf20Sopenharmony_ci value &= 0xFFFBFFFF; 2928c2ecf20Sopenharmony_ci value |= 0x00040000; 2938c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 2948c2ecf20Sopenharmony_ci OUT_CTRL1 + (0x200 * i), value); 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci /* 2978c2ecf20Sopenharmony_ci * clear VPRES_VERT_EN bit, fixes the chroma run away problem 2988c2ecf20Sopenharmony_ci * when the input switching rate < 16 fields 2998c2ecf20Sopenharmony_ci */ 3008c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3018c2ecf20Sopenharmony_ci MISC_TIM_CTRL + (0x200 * i), &tmp); 3028c2ecf20Sopenharmony_ci /* disable special play detection */ 3038c2ecf20Sopenharmony_ci value = setBitAtPos(value, 14); 3048c2ecf20Sopenharmony_ci value = clearBitAtPos(value, 15); 3058c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3068c2ecf20Sopenharmony_ci MISC_TIM_CTRL + (0x200 * i), value); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci /* set vbi_gate_en to 0 */ 3098c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3108c2ecf20Sopenharmony_ci DFE_CTRL1 + (0x200 * i), &tmp); 3118c2ecf20Sopenharmony_ci value = clearBitAtPos(value, 29); 3128c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3138c2ecf20Sopenharmony_ci DFE_CTRL1 + (0x200 * i), value); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci medusa_PALCombInit(dev, i); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* Enable the generation of blue field output if no video */ 3188c2ecf20Sopenharmony_ci medusa_enable_bluefield_output(dev, i, 1); 3198c2ecf20Sopenharmony_ci } 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci for (i = 0; i < MAX_ENCODERS; i++) { 3228c2ecf20Sopenharmony_ci /* PAL hclock */ 3238c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3248c2ecf20Sopenharmony_ci DENC_A_REG_1 + (0x100 * i), &tmp); 3258c2ecf20Sopenharmony_ci value &= 0xF000FC00; 3268c2ecf20Sopenharmony_ci value |= 0x06C002D0; 3278c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3288c2ecf20Sopenharmony_ci DENC_A_REG_1 + (0x100 * i), value); 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci /* burst begin and burst end */ 3318c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3328c2ecf20Sopenharmony_ci DENC_A_REG_2 + (0x100 * i), &tmp); 3338c2ecf20Sopenharmony_ci value &= 0xFF000000; 3348c2ecf20Sopenharmony_ci value |= 0x007E9754; 3358c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3368c2ecf20Sopenharmony_ci DENC_A_REG_2 + (0x100 * i), value); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci /* hblank and vactive */ 3398c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3408c2ecf20Sopenharmony_ci DENC_A_REG_3 + (0x100 * i), &tmp); 3418c2ecf20Sopenharmony_ci value &= 0xFC00FE00; 3428c2ecf20Sopenharmony_ci value |= 0x00FC0120; 3438c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3448c2ecf20Sopenharmony_ci DENC_A_REG_3 + (0x100 * i), value); 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci /* set PAL vblank, phase alternation, 0 IRE pedestal */ 3478c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3488c2ecf20Sopenharmony_ci DENC_A_REG_4 + (0x100 * i), &tmp); 3498c2ecf20Sopenharmony_ci value &= 0x00FCFFFF; 3508c2ecf20Sopenharmony_ci value |= 0x14010000; 3518c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3528c2ecf20Sopenharmony_ci DENC_A_REG_4 + (0x100 * i), value); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], 3558c2ecf20Sopenharmony_ci DENC_A_REG_5 + (0x100 * i), &tmp); 3568c2ecf20Sopenharmony_ci value &= 0xFFFF0000; 3578c2ecf20Sopenharmony_ci value |= 0x0000F078; 3588c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3598c2ecf20Sopenharmony_ci DENC_A_REG_5 + (0x100 * i), value); 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3628c2ecf20Sopenharmony_ci DENC_A_REG_6 + (0x100 * i), 0x00A493CF); 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci /* Subcarrier Increment */ 3658c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], 3668c2ecf20Sopenharmony_ci DENC_A_REG_7 + (0x100 * i), 0x2A098ACB); 3678c2ecf20Sopenharmony_ci } 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci /* set picture resolutions */ 3708c2ecf20Sopenharmony_ci /* 0 - 720 */ 3718c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); 3728c2ecf20Sopenharmony_ci /* 0 - 576 */ 3738c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci /* set Bypass input format to PAL 625 lines */ 3768c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 3778c2ecf20Sopenharmony_ci value &= 0xFFF7FDFF; 3788c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci return ret_val; 3818c2ecf20Sopenharmony_ci} 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ciint medusa_set_videostandard(struct cx25821_dev *dev) 3848c2ecf20Sopenharmony_ci{ 3858c2ecf20Sopenharmony_ci int status = 0; 3868c2ecf20Sopenharmony_ci u32 value = 0, tmp = 0; 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) 3898c2ecf20Sopenharmony_ci status = medusa_initialize_pal(dev); 3908c2ecf20Sopenharmony_ci else 3918c2ecf20Sopenharmony_ci status = medusa_initialize_ntsc(dev); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci /* Enable DENC_A output */ 3948c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp); 3958c2ecf20Sopenharmony_ci value = setBitAtPos(value, 4); 3968c2ecf20Sopenharmony_ci status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value); 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci /* Enable DENC_B output */ 3998c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp); 4008c2ecf20Sopenharmony_ci value = setBitAtPos(value, 4); 4018c2ecf20Sopenharmony_ci status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value); 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci return status; 4048c2ecf20Sopenharmony_ci} 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_civoid medusa_set_resolution(struct cx25821_dev *dev, int width, 4078c2ecf20Sopenharmony_ci int decoder_select) 4088c2ecf20Sopenharmony_ci{ 4098c2ecf20Sopenharmony_ci int decoder = 0; 4108c2ecf20Sopenharmony_ci int decoder_count = 0; 4118c2ecf20Sopenharmony_ci u32 hscale = 0x0; 4128c2ecf20Sopenharmony_ci u32 vscale = 0x0; 4138c2ecf20Sopenharmony_ci const int MAX_WIDTH = 720; 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci /* validate the width */ 4168c2ecf20Sopenharmony_ci if (width > MAX_WIDTH) { 4178c2ecf20Sopenharmony_ci pr_info("%s(): width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH\n", 4188c2ecf20Sopenharmony_ci __func__, width, MAX_WIDTH); 4198c2ecf20Sopenharmony_ci width = MAX_WIDTH; 4208c2ecf20Sopenharmony_ci } 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci if (decoder_select <= 7 && decoder_select >= 0) { 4238c2ecf20Sopenharmony_ci decoder = decoder_select; 4248c2ecf20Sopenharmony_ci decoder_count = decoder_select + 1; 4258c2ecf20Sopenharmony_ci } else { 4268c2ecf20Sopenharmony_ci decoder = 0; 4278c2ecf20Sopenharmony_ci decoder_count = dev->_max_num_decoders; 4288c2ecf20Sopenharmony_ci } 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci switch (width) { 4318c2ecf20Sopenharmony_ci case 320: 4328c2ecf20Sopenharmony_ci hscale = 0x13E34B; 4338c2ecf20Sopenharmony_ci vscale = 0x0; 4348c2ecf20Sopenharmony_ci break; 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci case 352: 4378c2ecf20Sopenharmony_ci hscale = 0x10A273; 4388c2ecf20Sopenharmony_ci vscale = 0x0; 4398c2ecf20Sopenharmony_ci break; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci case 176: 4428c2ecf20Sopenharmony_ci hscale = 0x3115B2; 4438c2ecf20Sopenharmony_ci vscale = 0x1E00; 4448c2ecf20Sopenharmony_ci break; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci case 160: 4478c2ecf20Sopenharmony_ci hscale = 0x378D84; 4488c2ecf20Sopenharmony_ci vscale = 0x1E00; 4498c2ecf20Sopenharmony_ci break; 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_ci default: /* 720 */ 4528c2ecf20Sopenharmony_ci hscale = 0x0; 4538c2ecf20Sopenharmony_ci vscale = 0x0; 4548c2ecf20Sopenharmony_ci break; 4558c2ecf20Sopenharmony_ci } 4568c2ecf20Sopenharmony_ci 4578c2ecf20Sopenharmony_ci for (; decoder < decoder_count; decoder++) { 4588c2ecf20Sopenharmony_ci /* write scaling values for each decoder */ 4598c2ecf20Sopenharmony_ci cx25821_i2c_write(&dev->i2c_bus[0], 4608c2ecf20Sopenharmony_ci HSCALE_CTRL + (0x200 * decoder), hscale); 4618c2ecf20Sopenharmony_ci cx25821_i2c_write(&dev->i2c_bus[0], 4628c2ecf20Sopenharmony_ci VSCALE_CTRL + (0x200 * decoder), vscale); 4638c2ecf20Sopenharmony_ci } 4648c2ecf20Sopenharmony_ci} 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_cistatic void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder, 4678c2ecf20Sopenharmony_ci int duration) 4688c2ecf20Sopenharmony_ci{ 4698c2ecf20Sopenharmony_ci u32 fld_cnt = 0; 4708c2ecf20Sopenharmony_ci u32 tmp = 0; 4718c2ecf20Sopenharmony_ci u32 disp_cnt_reg = DISP_AB_CNT; 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci /* no support */ 4748c2ecf20Sopenharmony_ci if (decoder < VDEC_A || decoder > VDEC_H) { 4758c2ecf20Sopenharmony_ci return; 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci switch (decoder) { 4798c2ecf20Sopenharmony_ci default: 4808c2ecf20Sopenharmony_ci break; 4818c2ecf20Sopenharmony_ci case VDEC_C: 4828c2ecf20Sopenharmony_ci case VDEC_D: 4838c2ecf20Sopenharmony_ci disp_cnt_reg = DISP_CD_CNT; 4848c2ecf20Sopenharmony_ci break; 4858c2ecf20Sopenharmony_ci case VDEC_E: 4868c2ecf20Sopenharmony_ci case VDEC_F: 4878c2ecf20Sopenharmony_ci disp_cnt_reg = DISP_EF_CNT; 4888c2ecf20Sopenharmony_ci break; 4898c2ecf20Sopenharmony_ci case VDEC_G: 4908c2ecf20Sopenharmony_ci case VDEC_H: 4918c2ecf20Sopenharmony_ci disp_cnt_reg = DISP_GH_CNT; 4928c2ecf20Sopenharmony_ci break; 4938c2ecf20Sopenharmony_ci } 4948c2ecf20Sopenharmony_ci 4958c2ecf20Sopenharmony_ci /* update hardware */ 4968c2ecf20Sopenharmony_ci fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp); 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_ci if (!(decoder % 2)) { /* EVEN decoder */ 4998c2ecf20Sopenharmony_ci fld_cnt &= 0xFFFF0000; 5008c2ecf20Sopenharmony_ci fld_cnt |= duration; 5018c2ecf20Sopenharmony_ci } else { 5028c2ecf20Sopenharmony_ci fld_cnt &= 0x0000FFFF; 5038c2ecf20Sopenharmony_ci fld_cnt |= ((u32) duration) << 16; 5048c2ecf20Sopenharmony_ci } 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt); 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci/* Map to Medusa register setting */ 5108c2ecf20Sopenharmony_cistatic int mapM(int srcMin, int srcMax, int srcVal, int dstMin, int dstMax, 5118c2ecf20Sopenharmony_ci int *dstVal) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci int numerator; 5148c2ecf20Sopenharmony_ci int denominator; 5158c2ecf20Sopenharmony_ci int quotient; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) 5188c2ecf20Sopenharmony_ci return -1; 5198c2ecf20Sopenharmony_ci /* 5208c2ecf20Sopenharmony_ci * This is the overall expression used: 5218c2ecf20Sopenharmony_ci * *dstVal = 5228c2ecf20Sopenharmony_ci * (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin; 5238c2ecf20Sopenharmony_ci * but we need to account for rounding so below we use the modulus 5248c2ecf20Sopenharmony_ci * operator to find the remainder and increment if necessary. 5258c2ecf20Sopenharmony_ci */ 5268c2ecf20Sopenharmony_ci numerator = (srcVal - srcMin) * (dstMax - dstMin); 5278c2ecf20Sopenharmony_ci denominator = srcMax - srcMin; 5288c2ecf20Sopenharmony_ci quotient = numerator / denominator; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci if (2 * (numerator % denominator) >= denominator) 5318c2ecf20Sopenharmony_ci quotient++; 5328c2ecf20Sopenharmony_ci 5338c2ecf20Sopenharmony_ci *dstVal = quotient + dstMin; 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci return 0; 5368c2ecf20Sopenharmony_ci} 5378c2ecf20Sopenharmony_ci 5388c2ecf20Sopenharmony_cistatic unsigned long convert_to_twos(long numeric, unsigned long bits_len) 5398c2ecf20Sopenharmony_ci{ 5408c2ecf20Sopenharmony_ci unsigned char temp; 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci if (numeric >= 0) 5438c2ecf20Sopenharmony_ci return numeric; 5448c2ecf20Sopenharmony_ci else { 5458c2ecf20Sopenharmony_ci temp = ~(abs(numeric) & 0xFF); 5468c2ecf20Sopenharmony_ci temp += 1; 5478c2ecf20Sopenharmony_ci return temp; 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci} 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ciint medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder) 5528c2ecf20Sopenharmony_ci{ 5538c2ecf20Sopenharmony_ci int ret_val = 0; 5548c2ecf20Sopenharmony_ci int value = 0; 5558c2ecf20Sopenharmony_ci u32 val = 0, tmp = 0; 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci if ((brightness > VIDEO_PROCAMP_MAX) || 5588c2ecf20Sopenharmony_ci (brightness < VIDEO_PROCAMP_MIN)) { 5598c2ecf20Sopenharmony_ci return -1; 5608c2ecf20Sopenharmony_ci } 5618c2ecf20Sopenharmony_ci ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness, 5628c2ecf20Sopenharmony_ci SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); 5638c2ecf20Sopenharmony_ci value = convert_to_twos(value, 8); 5648c2ecf20Sopenharmony_ci val = cx25821_i2c_read(&dev->i2c_bus[0], 5658c2ecf20Sopenharmony_ci VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp); 5668c2ecf20Sopenharmony_ci val &= 0xFFFFFF00; 5678c2ecf20Sopenharmony_ci ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], 5688c2ecf20Sopenharmony_ci VDEC_A_BRITE_CTRL + (0x200 * decoder), val | value); 5698c2ecf20Sopenharmony_ci return ret_val; 5708c2ecf20Sopenharmony_ci} 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_ciint medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder) 5738c2ecf20Sopenharmony_ci{ 5748c2ecf20Sopenharmony_ci int ret_val = 0; 5758c2ecf20Sopenharmony_ci int value = 0; 5768c2ecf20Sopenharmony_ci u32 val = 0, tmp = 0; 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_ci if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) { 5798c2ecf20Sopenharmony_ci return -1; 5808c2ecf20Sopenharmony_ci } 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast, 5838c2ecf20Sopenharmony_ci UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); 5848c2ecf20Sopenharmony_ci val = cx25821_i2c_read(&dev->i2c_bus[0], 5858c2ecf20Sopenharmony_ci VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp); 5868c2ecf20Sopenharmony_ci val &= 0xFFFFFF00; 5878c2ecf20Sopenharmony_ci ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], 5888c2ecf20Sopenharmony_ci VDEC_A_CNTRST_CTRL + (0x200 * decoder), val | value); 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci return ret_val; 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ciint medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci int ret_val = 0; 5968c2ecf20Sopenharmony_ci int value = 0; 5978c2ecf20Sopenharmony_ci u32 val = 0, tmp = 0; 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) { 6008c2ecf20Sopenharmony_ci return -1; 6018c2ecf20Sopenharmony_ci } 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, 6048c2ecf20Sopenharmony_ci SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value); 6058c2ecf20Sopenharmony_ci 6068c2ecf20Sopenharmony_ci value = convert_to_twos(value, 8); 6078c2ecf20Sopenharmony_ci val = cx25821_i2c_read(&dev->i2c_bus[0], 6088c2ecf20Sopenharmony_ci VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp); 6098c2ecf20Sopenharmony_ci val &= 0xFFFFFF00; 6108c2ecf20Sopenharmony_ci 6118c2ecf20Sopenharmony_ci ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], 6128c2ecf20Sopenharmony_ci VDEC_A_HUE_CTRL + (0x200 * decoder), val | value); 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci return ret_val; 6158c2ecf20Sopenharmony_ci} 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ciint medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder) 6188c2ecf20Sopenharmony_ci{ 6198c2ecf20Sopenharmony_ci int ret_val = 0; 6208c2ecf20Sopenharmony_ci int value = 0; 6218c2ecf20Sopenharmony_ci u32 val = 0, tmp = 0; 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_ci if ((saturation > VIDEO_PROCAMP_MAX) || 6248c2ecf20Sopenharmony_ci (saturation < VIDEO_PROCAMP_MIN)) { 6258c2ecf20Sopenharmony_ci return -1; 6268c2ecf20Sopenharmony_ci } 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci ret_val = mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation, 6298c2ecf20Sopenharmony_ci UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value); 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci val = cx25821_i2c_read(&dev->i2c_bus[0], 6328c2ecf20Sopenharmony_ci VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp); 6338c2ecf20Sopenharmony_ci val &= 0xFFFFFF00; 6348c2ecf20Sopenharmony_ci ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], 6358c2ecf20Sopenharmony_ci VDEC_A_USAT_CTRL + (0x200 * decoder), val | value); 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci val = cx25821_i2c_read(&dev->i2c_bus[0], 6388c2ecf20Sopenharmony_ci VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp); 6398c2ecf20Sopenharmony_ci val &= 0xFFFFFF00; 6408c2ecf20Sopenharmony_ci ret_val |= cx25821_i2c_write(&dev->i2c_bus[0], 6418c2ecf20Sopenharmony_ci VDEC_A_VSAT_CTRL + (0x200 * decoder), val | value); 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci return ret_val; 6448c2ecf20Sopenharmony_ci} 6458c2ecf20Sopenharmony_ci 6468c2ecf20Sopenharmony_ci/* Program the display sequence and monitor output. */ 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ciint medusa_video_init(struct cx25821_dev *dev) 6498c2ecf20Sopenharmony_ci{ 6508c2ecf20Sopenharmony_ci u32 value = 0, tmp = 0; 6518c2ecf20Sopenharmony_ci int ret_val = 0; 6528c2ecf20Sopenharmony_ci int i = 0; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci /* disable Auto source selection on all video decoders */ 6558c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); 6568c2ecf20Sopenharmony_ci value &= 0xFFFFF0FF; 6578c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci if (ret_val < 0) 6608c2ecf20Sopenharmony_ci goto error; 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci /* Turn off Master source switch enable */ 6638c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp); 6648c2ecf20Sopenharmony_ci value &= 0xFFFFFFDF; 6658c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value); 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci if (ret_val < 0) 6688c2ecf20Sopenharmony_ci goto error; 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci /* 6718c2ecf20Sopenharmony_ci * FIXME: due to a coding bug the duration was always 0. It's 6728c2ecf20Sopenharmony_ci * likely that it really should be something else, but due to the 6738c2ecf20Sopenharmony_ci * lack of documentation I have no idea what it should be. For 6748c2ecf20Sopenharmony_ci * now just fill in 0 as the duration. 6758c2ecf20Sopenharmony_ci */ 6768c2ecf20Sopenharmony_ci for (i = 0; i < dev->_max_num_decoders; i++) 6778c2ecf20Sopenharmony_ci medusa_set_decoderduration(dev, i, 0); 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci /* Select monitor as DENC A input, power up the DAC */ 6808c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp); 6818c2ecf20Sopenharmony_ci value &= 0xFF70FF70; 6828c2ecf20Sopenharmony_ci value |= 0x00090008; /* set en_active */ 6838c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value); 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_ci if (ret_val < 0) 6868c2ecf20Sopenharmony_ci goto error; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci /* enable input is VIP/656 */ 6898c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp); 6908c2ecf20Sopenharmony_ci value |= 0x00040100; /* enable VIP */ 6918c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value); 6928c2ecf20Sopenharmony_ci 6938c2ecf20Sopenharmony_ci if (ret_val < 0) 6948c2ecf20Sopenharmony_ci goto error; 6958c2ecf20Sopenharmony_ci 6968c2ecf20Sopenharmony_ci /* select AFE clock to output mode */ 6978c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp); 6988c2ecf20Sopenharmony_ci value &= 0x83FFFFFF; 6998c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, 7008c2ecf20Sopenharmony_ci value | 0x10000000); 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci if (ret_val < 0) 7038c2ecf20Sopenharmony_ci goto error; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci /* Turn on all of the data out and control output pins. */ 7068c2ecf20Sopenharmony_ci value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp); 7078c2ecf20Sopenharmony_ci value &= 0xFEF0FE00; 7088c2ecf20Sopenharmony_ci if (dev->_max_num_decoders == MAX_DECODERS) { 7098c2ecf20Sopenharmony_ci /* 7108c2ecf20Sopenharmony_ci * Note: The octal board does not support control pins(bit16-19) 7118c2ecf20Sopenharmony_ci * These bits are ignored in the octal board. 7128c2ecf20Sopenharmony_ci * 7138c2ecf20Sopenharmony_ci * disable VDEC A-C port, default to Mobilygen Interface 7148c2ecf20Sopenharmony_ci */ 7158c2ecf20Sopenharmony_ci value |= 0x010001F8; 7168c2ecf20Sopenharmony_ci } else { 7178c2ecf20Sopenharmony_ci /* disable VDEC A-C port, default to Mobilygen Interface */ 7188c2ecf20Sopenharmony_ci value |= 0x010F0108; 7198c2ecf20Sopenharmony_ci } 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci value |= 7; 7228c2ecf20Sopenharmony_ci ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value); 7238c2ecf20Sopenharmony_ci 7248c2ecf20Sopenharmony_ci if (ret_val < 0) 7258c2ecf20Sopenharmony_ci goto error; 7268c2ecf20Sopenharmony_ci 7278c2ecf20Sopenharmony_ci ret_val = medusa_set_videostandard(dev); 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_cierror: 7308c2ecf20Sopenharmony_ci return ret_val; 7318c2ecf20Sopenharmony_ci} 732