2025-05-10 21:58:58 +08:00

1789 lines
63 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// SPDX-License-Identifier: GPL-2.0
/********************************************************************************
*
* Copyright (C) 2017 NEXTCHIP Inc. All rights reserved.
* Module : The decoder's video format module
* Description : Video format
* Author :
* Date :
* Version : Version 2.0
*
********************************************************************************
* History :
*
*
********************************************************************************/
#include <linux/string.h>
#include <linux/delay.h>
//#include "eq_common.h"
#include "nvp6158_video.h"
#include "nvp6158_video_auto_detect.h"
#include "nvp6158_coax_protocol.h"
//#include "acp.h"
#include "nvp6158_video_eq.h"
#define _ENABLE_DET_DEBOUNCE_
#define AHD_720P30_Detect_Count 1 //1:1time 0:2time check //2020-12-16
/*******************************************************************************
* extern variable
*******************************************************************************/
extern unsigned int nvp6158_cnt;
extern int nvp6158_chip_id[4];
extern unsigned int nvp6158_g_vloss;
extern unsigned int nvp6158_iic_addr[4];
unsigned char nvp6158_g_ch_video_fmt[16] = {[0 ... 15] = 0xFF}; // save user's video format
extern unsigned char nvp6158_det_mode[16];
extern unsigned int nvp6158_gCoaxFirmUpdateFlag[16];
unsigned char nvp6158_motion_sens_tbl[8]= {0xe0,0xc8,0xa0,0x98,0x78,0x68,0x50,0x48};
unsigned char nvp6158_ch_mode_status[16]={[0 ... 15]=0xff};
unsigned char nvp6158_ch_vfmt_status[16]={[0 ... 15]=0xff};
#ifdef _ENABLE_DET_DEBOUNCE_
NVP6158_INFORMATION_S nvp6158_s_raptor3_vfmts;
#endif
void nvp6158_dump_reg( unsigned char ch, unsigned char bank )
{
int tmp = 0;
int i = 0, j= 0;
printk("***************IIC ADDR 0x%02x - CH[%02d] *****************\r\n", nvp6158_iic_addr[ch/4], ch );
printk("***************Chip[0x%02x] Bank[0x%x]*****************\r\n", nvp6158_iic_addr[ch/4], bank );
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, bank );
for (i = 0;i<=0xF;i++)
{
if(i==0)
{
printk(" 0x%02x ",i);
}
else if (i==0xF)
{
printk("0x%02x\r\n",i);
}
else
{
printk("0x%02x ",i);
}
}
for (i = 0;i<=0xF;i++)
{
for(j = 0;j<=0xF;j++)
{
tmp = gpio_i2c_read(nvp6158_iic_addr[ch/4], (i<<4)|j);
if (j==0)
{
printk("0x%02x-0x%02x ",(i<<4)|j,tmp);
}
else if (j==0xF)
{
printk("0x%02x\r\n",tmp);
}
else
{
printk("0x%02x ",tmp);
}
}
}
}
unsigned char nvp6158_video_get_adcclk(unsigned char ch)
{
unsigned char adc_value;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x01);
adc_value = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x84+ch%4);
printk(">>>>> DRV[%s:%d] CH:%d, Bank:0x%02x, ADC clock delay:0x%x\n", __func__, __LINE__, ch, nvp6158_iic_addr[ch/4], adc_value );
return adc_value;
}
void nvp6158_video_set_adcclk(unsigned char ch, unsigned char value)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x01);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x84+ch%4, value);
printk(">>>>> DRV[%s:%d] CH:%d, Bank:0x%02x, ADC clock delay:0x%x\n", __func__, __LINE__, ch, nvp6158_iic_addr[ch/4], value );
}
static __maybe_unused void NVP6158_set_afe(unsigned char ch, unsigned char onoff)
{
unsigned char afe_value;
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
afe_value = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x00+ch%4);
if(onoff==1)
_CLE_BIT(afe_value, 0);
else
_SET_BIT(afe_value, 0);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x00+ch%4, afe_value);
msleep(10);
printk("NVP6158_set_afe ch[%d] [%s] done\n", ch, onoff?"ON":"OFF");
}
}
static __maybe_unused void nvp6158_datareverse(unsigned char chip, unsigned char port)
{
/*
BANK1 0xCB[3:0],ÿ<><C3BF>bit<69><74><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>bt656<35><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><31><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><30><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
unsigned char tmp;
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
tmp = gpio_i2c_read(nvp6158_iic_addr[chip], 0xCB);
_SET_BIT(tmp, port);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xCB, tmp);
printk("nvp6158[%d] port[%d] data reversed\n", chip, port);
}
static __maybe_unused void nvp6158_pll_bypass(unsigned char chip, int flag)
{
unsigned char val_1x81;
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
val_1x81 = gpio_i2c_read(nvp6158_iic_addr[chip], 0x81);
if(flag == 1)
{
val_1x81 |= 0x02;
}
else
{
val_1x81 &= 0xFD;
}
gpio_i2c_write(nvp6158_iic_addr[chip], 0x81, val_1x81);
}
static void nvp6158_system_init(unsigned char chip)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x80, 0x0F);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x80, 0x40);
msleep(30);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x80, 0x61);
msleep(30);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x80, 0x60);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
gpio_i2c_write(nvp6158_iic_addr[chip], 0xCA, 0x66); //NVP6158C/6158B ONLY HAS 2 PORTS
else
gpio_i2c_write(nvp6158_iic_addr[chip], 0xCA, 0xFF); //NVP6158 HAS 4 PORTS
printk("nvp6158[C]_system_init\n");
}
/*******************************************************************************
* Description : Initialize common value of AHD
* Argurments : dec(slave address)
* Return value : rev ID
* Modify :
* warning :
*******************************************************************************/
void nvp6158_common_init(unsigned char chip)
{
int ch;
/* initialize chip */
nvp6158_system_init(chip);
//VDO_1/2 disabled, VCLK_x disabled
gpio_i2c_write(0x60, 0xFF, 0x01);
gpio_i2c_write(0x60, 0xCA, 0x00);
for(ch=0;ch<4;ch++)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
//gpio_i2c_write(nvp6158_iic_addr[chip], 0x00+ch, 0x10);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x22+4*ch, 0x0B);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x23+4*ch, 0x41);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x05+ch%4);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x00, 0xD0); // Clamp speed
gpio_i2c_write(nvp6158_iic_addr[chip], 0xA9, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x76, 0x00);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0x00);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xD5, 0x80);
}
}
#define MAX_DEBOUNCE_CNT 5
static int nvp6158_AutoDebouceCheck( unsigned char ch, NVP6158_INFORMATION_S *pInformation )
{
int i;
int ret = 0;
//unsigned char oDevNum = 0;
unsigned char oDebncIdx = 0;
unsigned char oVfc = 0;
NC_VIVO_CH_FORMATDEF oFmtB5Def;
video_input_vfc sVFC;
//decoder_dev_ch_info_s sDevChInfo;
sVFC.ch = ch % 4;
sVFC.devnum = ch / 4;
nvp6158_video_input_onvideo_check_data(&sVFC);
oDebncIdx = pInformation->debounceidx[ch];
pInformation->debounce[ch][oDebncIdx%MAX_DEBOUNCE_CNT] = sVFC.vfc;
/* For Debug Ch1 Only */
/*
if( ch == 0)
printk("debunce:0x%02X, debncIdx:%d\n", pInformation->debounce[ch][pInformation->debounceidx[ch]], pInformation->debounceidx[ch]);
*/
pInformation->debounceidx[ch]++;
pInformation->debounceidx[ch] = ( (pInformation->debounceidx[ch] % MAX_DEBOUNCE_CNT) == 0 ) ? 0 : pInformation->debounceidx[ch];
oVfc = pInformation->debounce[ch][pInformation->debounceidx[ch]];
for( i = 0; i < MAX_DEBOUNCE_CNT; i++ )
{
if( oVfc != pInformation->debounce[ch][i])
{
break;
}
}
if( i == MAX_DEBOUNCE_CNT )
{
oFmtB5Def = NVP6158_NC_VD_AUTO_VFCtoFMTDEF(ch, oVfc);
//if( ( oFmtB5Def != AHD30_5M_20P ) && ( oFmtB5Def != pInformation->prevideofmt[ch] ) )
if( ( ( oFmtB5Def != AHD30_5M_20P ) && ( oFmtB5Def != CVI_8M_15P ) &&
( oFmtB5Def != CVI_8M_12_5P ) && ( oFmtB5Def != CVI_HD_30P_EX ) &&
( oFmtB5Def != AHD20_1080P_25P ) && ( oFmtB5Def != AHD20_1080P_30P ) &&
( oFmtB5Def != CVI_FHD_25P ) )
&& ( oFmtB5Def != pInformation->prevideofmt[ch] ) )
{
printk("\n\n\n>>>>>>WATCH OUT<<<<<<ch[%d] oVfc[%2x]oFmtB5Def[%2x] != pInformation->prevideofmt[%2x]\n\n\n", ch, oVfc, oFmtB5Def , pInformation->prevideofmt[ch]);
ret = -1;
}
}
return ret;
}
void nvp6158_channel_reset(unsigned char ch)
{
unsigned char reg_1x97, bank_save;
bank_save = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0xFF);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x01);
reg_1x97 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x97);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x97, reg_1x97&(~(1<<(ch%4))));
msleep(30);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x97, reg_1x97|0x0F);
msleep(30);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, bank_save);
printk("CH[%d] channel been resetted\n", ch);
}
void nvp6158_set_colorpattern(void)
{
int chip;
for(chip=0;chip<nvp6158_cnt;chip++)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0xaa);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x79, 0xaa);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x05);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x90);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x06);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x90);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x07);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x90);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x90);
}
}
void nvp6158_set_colorpattern2(void)
{
int chip;
printk("[NVP6158_VIDEO] %s(%d) \n", __func__, __LINE__);
for(chip=0;chip<nvp6158_cnt;chip++)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x05);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x06);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x07);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
/* gpio_i2c_write(nvp6158_iic_addr[0], 0x78, 0x42);//ch1:Blue *//* ch2:Yellow ch3:Green ch4:Red */
/* gpio_i2c_write(nvp6158_iic_addr[0], 0x79, 0x76); */
gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0xce); /* ch1:Blue ch2:Yellow ch3:Green ch4:Red */
gpio_i2c_write(nvp6158_iic_addr[chip], 0x79, 0xba);
}
}
void nvp6158_set_colorpattern3(void)
{
int chip;
printk("[NVP6158_VIDEO] %s(%d) \n", __func__, __LINE__);
for(chip=0;chip<nvp6158_cnt;chip++)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x05);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x06);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x07);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x2c, 0x08);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x6a, 0x80);
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
/* gpio_i2c_write(nvp6158_iic_addr[0], 0x78, 0x42); //ch1:Green ch2:Green ch3:Green ch4:Green */
/* gpio_i2c_write(nvp6158_iic_addr[0], 0x79, 0x76); */
gpio_i2c_write(nvp6158_iic_addr[chip], 0x78, 0x44); /* ch1:Green ch2:Green ch3:Green ch4:Green */
gpio_i2c_write(nvp6158_iic_addr[chip], 0x79, 0x44);
}
}
static __maybe_unused void nvp6158_adc_reset(unsigned char ch)
{
unsigned char bank_save;
bank_save = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0xFF);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x05+ch%4);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x0B, 0xF0);
msleep(30);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x0B, 0x0F);
msleep(30);
printk("CH[%d] adc been resetted\n", ch);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, bank_save);
}
static int nvp6158_GetFormatEachCh( unsigned char ch, NVP6158_INFORMATION_S *pInformation )
{
video_input_vfc sVFC;
video_input_vfc svin_vfc_bak;
video_input_novid sNoVideo;
NC_VIVO_CH_FORMATDEF oCurVidFmt;
//NC_VIDEO_ONOFF oCurVideoloss;
/* initialize current video format - pInformation structure is for app */
pInformation->curvideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
pInformation->curvideoloss[ch] = VIDEO_LOSS_OFF;
pInformation->vfc[ch] = 0xff;
/* initialize vfc(B5xF0) and videoloss information(B0xA8) */
sVFC.ch = ch%4;
sVFC.devnum = ch/4;
sNoVideo.ch = ch%4;
sNoVideo.devnum = ch/4;
/* get vfc and videoloss */
if(nvp6158_chip_id[ch/4]==NVP6158C_R0_ID || nvp6158_chip_id[ch/4]==NVP6158_R0_ID)
nvp6158_video_input_vfc_read(&sVFC);
else
nvp6168_video_input_vfc_read(&sVFC);
nvp6158_video_input_novid_read(&sNoVideo);
svin_vfc_bak.ch = ch%4;
svin_vfc_bak.devnum = ch/4;
if(nvp6158_chip_id[ch/4]==NVP6158C_R0_ID || nvp6158_chip_id[ch/4]==NVP6158_R0_ID)
nvp6158_video_input_onvideo_check_data(&svin_vfc_bak);
/* check vfc&videoloss and run debounce */
if(((((sVFC.vfc >> 4 ) & 0xF) != 0xF) && ((sVFC.vfc & 0x0F) != 0xF)) && !sNoVideo.novid) // OnVideo
{
/* convert vfc to formatDefine for APP and save videoloss information */
oCurVidFmt = NVP6158_NC_VD_AUTO_VFCtoFMTDEF(ch, sVFC.vfc);
/* debouce */
pInformation->curvideofmt[ch] = oCurVidFmt;
pInformation->vfc[ch] = sVFC.vfc;
}
else if(((((sVFC.vfc >> 4 ) & 0xF) == 0xF) && ((sVFC.vfc & 0x0F) == 0xF)) && !sNoVideo.novid)
{
if(nvp6158_chip_id[ch/4]==NVP6158C_R0_ID || nvp6158_chip_id[ch/4]==NVP6158_R0_ID)
{
if(svin_vfc_bak.vfc == 0xFF)
{
//nvp6158_channel_reset(ch);
//nvp6158_adc_reset(ch);
}
}
}
/* check novideo option */
if( !sNoVideo.novid )
{
pInformation->curvideoloss[ch] = VIDEO_LOSS_ON;
}
return 0;
}
/*******************************************************************************
* Description : get videoloss information and get video format.
* Argurments : pvideofmt(video format buffer point)
* Return value : vloss(video loss information)
* Modify :
* warning :
*******************************************************************************/
#if(AHD_720P30_Detect_Count == 0)
static int CVI_720P30[16]={0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,};
#else
static int CVI_720P30[16]={1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}; //2020-12-16 for ahd 720p30 detect slow
#endif
unsigned int nvp6158_video_fmt_det(const unsigned char ch, NVP6158_INFORMATION_S *ps_nvp6158_vfmts)
{
int ret;
unsigned char oCurVideofmt = 0x00;
unsigned char oPreVideofmt = 0x00;
NC_VIVO_CH_FORMATDEF oFmtDef;
decoder_dev_ch_info_s sDevChInfo;
video_input_vfc sVFC_B13;
video_input_vfc sVFC_B5;
//for(ch=0; ch<nvp6158_cnt*4; ch++)
{
/* get video format */
nvp6158_GetFormatEachCh( ch, ps_nvp6158_vfmts );
/* process video format on/off */
oCurVideofmt = ps_nvp6158_vfmts->curvideofmt[ch];
oPreVideofmt = ps_nvp6158_vfmts->prevideofmt[ch];
if( ps_nvp6158_vfmts->curvideoloss[ch] == VIDEO_LOSS_ON)
{
/* on video */
if( (oCurVideofmt != NC_VIVO_CH_FORMATDEF_UNKNOWN) && (oPreVideofmt == NC_VIVO_CH_FORMATDEF_UNKNOWN) )
{
oFmtDef = NVP6158_NC_VD_AUTO_VFCtoFMTDEF( ch, ps_nvp6158_vfmts->vfc[ch] );
sDevChInfo.ch = ch%4;
sDevChInfo.devnum = ch/4;
sDevChInfo.fmt_def = oFmtDef;
if(oFmtDef == AHD30_5M_20P )
{
printk("[CH:%d] >> finding format: %x....\n", ch, oFmtDef);
nvp6158_video_input_ahd_tvi_distinguish(&sDevChInfo);
oFmtDef = sDevChInfo.fmt_def;
ps_nvp6158_vfmts->curvideofmt[ch] = oFmtDef;
}
else if( oFmtDef == CVI_8M_15P || oFmtDef == CVI_8M_12_5P )
{
if( oFmtDef == CVI_8M_15P )
printk("[CH:%d] >> finding format:CVI 8M 15P....\n", ch);
else
printk("[CH:%d] >> finding format:CVI 8M 12.5P....\n", ch);
if(-1 == nvp6158_video_input_cvi_tvi_distinguish(&sDevChInfo))
{
printk("error nvp6158_video_input_cvi_tvi_distinguish\n");
return 1;
}
oFmtDef = sDevChInfo.fmt_def;
if( oFmtDef == TVI_8M_15P )
{
printk("[CH:%d] >> changing format:TVI 8M 15P....\n", ch);
ps_nvp6158_vfmts->curvideofmt[ch] = TVI_8M_15P;
}
else if( oFmtDef == TVI_8M_12_5P )
{
printk("[CH:%d] >> changing format:TVI 8M 12_5P....\n", ch);
ps_nvp6158_vfmts->curvideofmt[ch] = TVI_8M_12_5P;
}
}
else if( oFmtDef == AHD20_720P_30P_EX_Btype/* || oFmtDef == CVI_HD_30P_EX*/)
{
if(CVI_720P30[ch] == 0)
{
oFmtDef = CVI_HD_30P_EX;
ps_nvp6158_vfmts->curvideofmt[ch] = CVI_HD_30P_EX;
CVI_720P30[ch] = 1;
printk("[CH:%d] >> AHD20_720P_30P_EX_Btype changing format:CVI CVI_HD_30P_EX ....\n", ch); //2020-12-16
}
else
printk("[CH:%d] >> AHD20_720P_30P_EX_Btype non changing format:CVI CVI_HD_30P_EX ....\n", ch); //2020-12-16
}
else if(oFmtDef == CVI_FHD_25P )
{
printk("[CH:%d] >> finding format: %x....\n", ch, oFmtDef);
nvp6158_video_input_cvi_ahd_1080p_distinguish(&sDevChInfo);
oFmtDef = sDevChInfo.fmt_def;
if( oFmtDef == AHD20_1080P_25P )
{
printk("[CH:%d] >> changing format:AHD 2M 25P....\n", ch);
ps_nvp6158_vfmts->curvideofmt[ch] = AHD20_1080P_25P;
}
}
if(ps_nvp6158_vfmts->vfc[ch] == 0x2B)
{
sDevChInfo.ch = ch%4;
sDevChInfo.devnum = ch/4;
sDevChInfo.fmt_def = ps_nvp6158_vfmts->vfc[ch];
nvp6158_video_input_ahd_tvi_distinguish(&sDevChInfo);
oFmtDef = sDevChInfo.fmt_def;
if( oFmtDef == TVI_4M_15P )
{
if((nvp6158_det_mode[ch] == NVP6158_DET_MODE_AUTO)||(nvp6158_det_mode[ch] == NVP6158_DET_MODE_TVI))
{
printk("[CH:%d] >> changing format:TVI 4M 15P....\n", ch);
ps_nvp6158_vfmts->curvideofmt[ch] = TVI_4M_15P;
}
else
ps_nvp6158_vfmts->curvideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
}
}
ps_nvp6158_vfmts->prevideofmt[ch] = ps_nvp6158_vfmts->curvideofmt[ch];
#ifdef _ENABLE_DET_DEBOUNCE_
nvp6158_s_raptor3_vfmts.debounce[ch][0] = 0; //clear debounce param status
nvp6158_s_raptor3_vfmts.debounce[ch][1] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][2] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][3] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][4] = 0;
nvp6158_s_raptor3_vfmts.debounceidx[ch] = 0;
nvp6158_s_raptor3_vfmts.prevideofmt[ch] = ps_nvp6158_vfmts->curvideofmt[ch]; //information for debounce.
#endif
//nvp6158_set_chnmode(ch, ps_nvp6158_vfmts->prevideofmt[ch]);
printk(">>>>> CH[%d], Set video format : 0x%02X\n", ch, oCurVideofmt);
}
else if( (oCurVideofmt == NC_VIVO_CH_FORMATDEF_UNKNOWN ) && (oPreVideofmt == NC_VIVO_CH_FORMATDEF_UNKNOWN) )
{
int ii = 0;
int retry_cnt = 0;
/* AHD 1080P, 720P NRT Detection Part */
/*
1. Check Bank13 0xF0
2. Check NoVideo Register ( Bank0 0xA8 )
3. Set Value 0x7f to Bank5 0x82
4. Read Bank13 0xf0
5. Read Bank5 0xf0
6. Check H Count
7. AHD 1080P or 720P Set
8. Set value 0x00 to bank5 0x82
*/
sVFC_B13.ch = ch%4;
sVFC_B13.devnum = ch / 4;
sVFC_B5.ch = ch%4;
sVFC_B5.devnum = ch / 4;
sDevChInfo.ch = ch%4;
sDevChInfo.devnum = ch / 4;
//nvp6158_video_input_manual_agc_stable_endi(&sDevChInfo, 1);
for(ii = 0; ii < 20; ii++ )
{
nvp6158_video_input_vfc_read( &sVFC_B13 );
nvp6158_video_input_onvideo_check_data( &sVFC_B5 );
if( ((sVFC_B5.vfc >> 4) & 0xf ) < 0x2)
{
break;
}
if( sVFC_B13.vfc == 0x2b && sVFC_B5.vfc == 0x3f)
{
printk("[DRV] CH[%d] Bank13 0xF0 [%02x], Bank5 0xF0[%02x]\n", ch, sVFC_B13.vfc, sVFC_B5.vfc );
printk("[DRV] CH[%d] AFHD 15P or 12.5P [%d]\n" , ch, retry_cnt );
break;
}
else if( ( sVFC_B5.vfc != 0x2f || sVFC_B5.vfc != 0x3f ) && (sVFC_B13.vfc != 0x2b))
{
printk("[DRV] CH[%d] Bank13 0xF0 [%02x], Bank5 0xF0[%02x]\n", ch, sVFC_B13.vfc, sVFC_B5.vfc );
printk("[DRV] CH[%d] Unknown Status [%d] \n", ch, retry_cnt );
}
if(retry_cnt >= 20 )
{
printk("CH[%d] Unknown Status Disitinguish Finished ...\n", ch );
break;
}
retry_cnt++;
msleep( 33 );
}
if( ((sVFC_B5.vfc >> 4) & 0xf ) < 0x2)
return 0;
nvp6158_video_input_ahd_nrt_distinguish( &sDevChInfo );
if( sDevChInfo.fmt_def == NC_VIVO_CH_FORMATDEF_UNKNOWN )
{
printk("[DRV] CH[%d] unknown format \n", ch);
return 0;
}
oFmtDef = sDevChInfo.fmt_def;
/* set video format(DEC) */
ps_nvp6158_vfmts->curvideofmt[ ch ] = oFmtDef;
ps_nvp6158_vfmts->prevideofmt[ch] = ps_nvp6158_vfmts->curvideofmt[ch];
#ifdef _ENABLE_DET_DEBOUNCE_
nvp6158_s_raptor3_vfmts.debounce[ch][0] = 0; //clear debounce param status
nvp6158_s_raptor3_vfmts.debounce[ch][1] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][2] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][3] = 0;
nvp6158_s_raptor3_vfmts.debounce[ch][4] = 0;
nvp6158_s_raptor3_vfmts.debounceidx[ch] = 0;
nvp6158_s_raptor3_vfmts.prevideofmt[ch] = ps_nvp6158_vfmts->curvideofmt[ch]; //information for debounce.
#endif
/* save onvideo to prevideofmt */
//nvp6158_s_raptor3_vfmts.prevideofmt[ch] = nvp6158_s_raptor3_vfmts.curvideofmt[ch];
//nvp6158_video_input_manual_agc_stable_endi(&sDevChInfo, 0);
printk(">>>>> CH[%d], Auto, Set video format : 0x%02X\n", ch, oCurVideofmt );
}
#ifdef _ENABLE_DET_DEBOUNCE_
else
{
ret = nvp6158_AutoDebouceCheck( ch, &nvp6158_s_raptor3_vfmts ); //note!!!!
if( ( ret == -1 ) && ( nvp6158_gCoaxFirmUpdateFlag[ch] == 0 ) )
{
sDevChInfo.ch = ch % 4;
sDevChInfo.devnum = ch/4;
/* hide decoder */
nvp6158_hide_ch(ch);
/* decoder afe power down */
nvp6158_video_input_vafe_control(&sDevChInfo, 0);
/* set no video- first(i:channel, raptor3_vfmts:information */
//nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
nvp6158_video_input_vafe_control(&sDevChInfo, 1);
/* for forced agc stable */
//nvp6158_video_input_manual_agc_stable_endi(&sDevChInfo, 0);
//msleep(50);
/* save onvideo to prevideofmt */
ps_nvp6158_vfmts->prevideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
nvp6158_s_raptor3_vfmts.prevideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
printk( ">>>>> CH[%d], Reset, Set No video : 0x%02X\n", ch, oCurVideofmt );
}
}
#endif
}
else
{
/* no video */
if( oPreVideofmt != NC_VIVO_CH_FORMATDEF_UNKNOWN )
{
//nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
ps_nvp6158_vfmts->prevideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
#if(AHD_720P30_Detect_Count == 0) //wait 2s to redetect
CVI_720P30[ch] = 0;
#else
CVI_720P30[ch] = 1; //2020-12-16
#endif
#ifdef _ENABLE_DET_DEBOUNCE_
nvp6158_s_raptor3_vfmts.prevideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
#endif
printk( ">>>>> CH[%d], Set No video : 0x%02X\n", ch, oCurVideofmt );
}
}
}
return ps_nvp6158_vfmts->prevideofmt[ch];
}
unsigned int nvp6168_video_fmt_det(const unsigned char ch, NVP6158_INFORMATION_S *ps_nvp6158_vfmts)
{
//int ret;
unsigned char oCurVideofmt = 0x00;
unsigned char oPreVideofmt = 0x00;
NC_VIVO_CH_FORMATDEF oFmtDef;
decoder_dev_ch_info_s sDevChInfo;
//video_input_vfc sVFC_B13;
//video_input_vfc sVFC_B5;
//for(ch=0; ch<nvp6158_cnt*4; ch++)
{
/* get video format */
nvp6158_GetFormatEachCh( ch, ps_nvp6158_vfmts );
/* process video format on/off */
oCurVideofmt = ps_nvp6158_vfmts->curvideofmt[ch];
oPreVideofmt = ps_nvp6158_vfmts->prevideofmt[ch];
if( ps_nvp6158_vfmts->curvideoloss[ch] == VIDEO_LOSS_ON)
{
/* on video */
if( (oCurVideofmt != NC_VIVO_CH_FORMATDEF_UNKNOWN) && (oPreVideofmt == NC_VIVO_CH_FORMATDEF_UNKNOWN) )
{
oFmtDef = NVP6158_NC_VD_AUTO_VFCtoFMTDEF( ch, ps_nvp6158_vfmts->vfc[ch] );
sDevChInfo.ch = ch%4;
sDevChInfo.devnum = ch/4;
sDevChInfo.fmt_def = oFmtDef;
if(oFmtDef == TVI_5M_20P) //needs 2nd identify
{
nvp6168_video_input_cvi_tvi_5M20p_distinguish(&sDevChInfo);
oFmtDef = sDevChInfo.fmt_def;
ps_nvp6158_vfmts->curvideofmt[ch] = oFmtDef;
}
ps_nvp6158_vfmts->prevideofmt[ch] = ps_nvp6158_vfmts->curvideofmt[ch];
//nvp6158_set_chnmode(ch, ps_nvp6158_vfmts->prevideofmt[ch]);
printk(">>>>> CH[%d], Set video format : 0x%02X\n", ch, oCurVideofmt);
}
}
else
{
/* no video */
if( oPreVideofmt != NC_VIVO_CH_FORMATDEF_UNKNOWN )
{
//nvp6158_set_chnmode(ch, NC_VIVO_CH_FORMATDEF_UNKNOWN);
ps_nvp6158_vfmts->prevideofmt[ch] = NC_VIVO_CH_FORMATDEF_UNKNOWN;
printk( ">>>>> CH[%d], Set No video : 0x%02X\n", ch, oCurVideofmt );
}
}
}
return ps_nvp6158_vfmts->prevideofmt[ch];
}
unsigned int nvp6158_getvideoloss(void)
{
unsigned int vloss=0, i;
unsigned char vlossperchip[4];
for(i=0;i<nvp6158_cnt;i++)
{
gpio_i2c_write(nvp6158_iic_addr[i], 0xFF, 0x00);
vlossperchip[i] = (gpio_i2c_read(nvp6158_iic_addr[i], 0xA8)&0x0F);
vloss |= (vlossperchip[i]<<(4*i));
}
return vloss;
}
static unsigned char nvp6158_vloss_pre = 0xFF;
static unsigned char nvp6158_ch_first_plug_status[8]={1,1,1,1,1,1,1,1};
static __maybe_unused unsigned char nvp6158_is_first_plugin(unsigned char ch)
{
unsigned int vloss=0;
vloss = nvp6158_getvideoloss();
//for(ch=0;ch<(nvp6158_cnt*4);ch++)
{
if( ( ((vloss>>ch)&0x01)==0 ) && ( ((nvp6158_vloss_pre>>ch)&0x01)==1 )) //video first input
{
nvp6158_ch_first_plug_status[ch] = 0;
nvp6158_vloss_pre &= ~(1<<ch); //corresponding bit, corresponding channel not in;
}
}
return nvp6158_ch_first_plug_status[ch];
}
void nvp6158_vd_chnreset(unsigned char ch)
{
unsigned char reg_1x97;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x01);
reg_1x97 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x97);
_CLE_BIT(reg_1x97,(ch%4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x97, reg_1x97);
msleep(10);
_SET_BIT(reg_1x97,(ch%4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x97, reg_1x97);
}
/*0:agc unlocked; 1:agc locked*/
int nvp6158_GetAgcLockStatus(unsigned char ch)
{
int agc_lock, ret;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
agc_lock = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0xE0);
ret = ((agc_lock>>(ch%4))&0x01);
return ret;
}
/*0:fsc unlocked; 1:fsc locked*/
int nvp6158_GetFSCLockStatus(unsigned char ch)
{
int fsc_lock, ret;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
fsc_lock = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0xE8+(ch%4));
ret = ((fsc_lock>>1)&0x01);
return ret;
}
void nvp6158_ResetFSCLock(unsigned char ch)
{
unsigned char acc_ref=0;
unsigned char check_cnt = 4;
do{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x05+(ch%4));
acc_ref = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x27);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x23, 0x80);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x27, 0x10);
msleep(35);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x23, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x27, acc_ref);
msleep(300);
}
while((nvp6158_GetFSCLockStatus(ch)==0) && ((check_cnt--)>0));
printk("%s, %d\n", __FUNCTION__, __LINE__);
}
void nvp6158_chn_killcolor(unsigned char ch, unsigned char onoff)
{
unsigned char colorkill;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
colorkill = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x22+(ch%4)*4);
if(onoff==1)
_SET_BIT(colorkill, 4);
else
_CLE_BIT(colorkill, 4);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x22+(ch%4)*4, colorkill);
printk("%s, %d %x %x\n", __FUNCTION__, __LINE__, onoff, colorkill);
}
void nvp6158_hide_ch(unsigned char ch)
{
unsigned char reg_0x7a;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
reg_0x7a = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x7A+((ch%4)/2));
reg_0x7a &= (ch%2==0?0xF0:0x0F);
reg_0x7a |= (ch%2==0?0x0F:0xF0);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x7A+((ch%4)/2),reg_0x7a);
//printk("%s, %d\n", __FUNCTION__, __LINE__);
}
void nvp6158_show_ch(unsigned char ch)
{
unsigned char reg_0x7a;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
reg_0x7a = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x7A+((ch%4)/2));
reg_0x7a &= (ch%2==0?0xF0:0x0F);
reg_0x7a |= (ch%2==0?0x01:0x10);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x7A+((ch%4)/2),reg_0x7a);
//printk("%s, %d\n", __FUNCTION__, __LINE__);
}
/*
support AHD 3M/4M real-time camera switch between NTSC and PAL
*/
int nvp6158_acp_SetVFmt(unsigned char ch, const unsigned char vfmt)
{
/*nvp6158_acp_rw_data_extention acpdata;
if((vfmt!=NTSC) && (vfmt!=PAL))
{
printk("%s vfmt[%d] out of range!!!\n", __FUNCTION__, vfmt);
return -1;
}
if(nvp6158_ch_vfmt_status[ch] == vfmt)
{
printk("%s vfmt is %d now!!!\n", __FUNCTION__, vfmt);
return -2;
}
acpdata.ch = ch;
acpdata.data[0] = 0x60; // register write
acpdata.data[1] = 0x82; // Output mode command
acpdata.data[2] = 0x19; // Output Format Change mode
acpdata.data[3] = 0x00; // Output Mode value
acpdata.data[4] = 0x00;
acpdata.data[5] = 0x00;
acpdata.data[6] = 0x00;
acpdata.data[7] = 0x00;
if( (nvp6158_ch_mode_status[ch] == NVP6158_VI_3M ||
nvp6158_ch_mode_status[ch] == NVP6158_VI_3M_NRT ||
nvp6158_ch_mode_status[ch] == NVP6158_VI_4M_NRT ||
nvp6158_ch_mode_status[ch] == NVP6158_VI_4M ) &&
nvp6158_GetAgcLockStatus(ch)==1)
{
acpdata.data[3] = vfmt^1; //CAUTION!!! IN CAMERA SIDE 0:PAL, 1:NTSC.
acp_isp_write_extention(ch, &acpdata);
msleep(100);
printk("%s change ch[%d] to %s!!!\n", __FUNCTION__, ch, vfmt==NTSC?"NTSC":"PAL");
}
*/
return 0;
}
void nvp6158_video_set_contrast(unsigned char ch, unsigned int value, unsigned int v_format)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x10+(ch%4)), value);
}
void nvp6158_video_set_brightness(unsigned char ch, unsigned int value, unsigned int v_format)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x0C+(ch%4)), value);
}
void nvp6158_video_set_saturation(unsigned char ch, unsigned int value, unsigned int v_format)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x3C+(ch%4)),value);
}
void nvp6158_video_set_hue(unsigned char ch, unsigned int value, unsigned int v_format)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x40+(ch%4)), value);
}
void nvp6158_video_set_sharpness(unsigned char ch, unsigned int value)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x14+(ch%4)), (0x90+value-100));
}
//u-gain value B0 0x44~0x47
void nvp6158_video_set_ugain(unsigned char ch, unsigned int value)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x44+(ch%4)), value);
}
//v-gain value B0 0x48~0x4b
void nvp6158_video_set_vgain(unsigned char ch, unsigned int value)
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], (0x48+(ch%4)), value);
}
void nvp6158_video_input_new_format_set(const unsigned char ch, const unsigned char chnmode)
{
unsigned char val_9x44;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x11);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x00 + ( (ch%4) * 0x20 ), 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF,0x09);
val_9x44 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x44);
val_9x44 &= ~(1 << (ch%4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x44, val_9x44);
/* CVI HD 30P PN Value Set */
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x50 + ( (ch%4) * 4 ) , 0x30);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x51 + ( (ch%4) * 4 ) , 0x6F);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x52 + ( (ch%4) * 4 ) , 0x67);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x53 + ( (ch%4) * 4 ) , 0x48);
}
static void nvp6158_set_chn_ycmerge(const unsigned char ch, unsigned char onoff)
{
unsigned char YCmerge, val5x69;
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x01);
YCmerge = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0xed);
_CLE_BIT(YCmerge, (ch%4));
if(onoff == 1)
_SET_BIT(YCmerge, (ch%4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xed, YCmerge);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x05+ch%4);
val5x69 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x69);
_CLE_BIT(val5x69, 4);
if(onoff == 1)
_SET_BIT(val5x69, 4);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x69, val5x69);
}
/*******************************************************************************
* Description : set this value
* Argurments : ch(channel)
* Return value : void
* Modify :
* warning : You don't have to change these values.
*******************************************************************************/
void nvp6158_set_chn_commonvalue(const unsigned char ch, const unsigned char chnmode)
{
decoder_dev_ch_info_s decoder_info;
unsigned char val_0x54;
unsigned char vfmt = chnmode%2;
if((chnmode <= AHD20_SD_H960_2EX_Btype_PAL) && (chnmode>=AHD20_SD_H960_NT))
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
val_0x54 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x54);
_CLE_BIT(val_0x54, (ch%4+4));
if(vfmt != PAL)
_SET_BIT(val_0x54, (ch%4+4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x54, val_0x54);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x05+ch%4);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x69,0x01);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xB8,0xB8);
}
else
{
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x00);
val_0x54 = gpio_i2c_read(nvp6158_iic_addr[ch/4], 0x54);
_CLE_BIT(val_0x54, (ch%4+4));
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x54, val_0x54);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xFF, 0x05+ch%4);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x69, 0x00);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xB8,0x39);
}
decoder_info.ch = ch%4;
decoder_info.devnum = ch/4;
decoder_info.fmt_def = chnmode;
if(__nvp6158_IsOver3MRTVideoFormat( &decoder_info ))
nvp6158_set_chn_ycmerge(ch, 1);
else
nvp6158_set_chn_ycmerge(ch, 0);
if(nvp6158_chip_id[decoder_info.devnum]==NVP6158C_R0_ID || nvp6158_chip_id[decoder_info.devnum]==NVP6158_R0_ID)
nvp6158_video_input_onvideo_set( &decoder_info );
else
nvp6168_video_input_onvideo_set( &decoder_info );
}
/*
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD>ģʽ
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ch: ͨ<><CDA8><EFBFBD>ţ<EFBFBD>ȡֵ<C8A1><D6B5>Χ0~(nvp6158_cnt*4-1)
vfmt: 0:NTSC, 1:PAL
chnmode:ͨ<><CDA8>ģʽ<C4A3><CABD><EFBFBD>ο<EFBFBD>NVP6158_VI_MODE.
*/
int nvp6158_set_chnmode(const unsigned char ch, const unsigned char chnmode)
{
//unsigned char tmp;
video_equalizer_info_s vin_eq_set;
video_input_novid auto_novid;
nvp6158_coax_str s_coax_str;
if(ch >= (nvp6158_cnt*4))
{
printk("func[nvp6158_set_chnmode] Channel %d is out of range!!!\n", ch);
return -1;
}
/* set video format each format */
if(chnmode < NC_VIVO_CH_FORMATDEF_MAX)
{
if(NC_VIVO_CH_FORMATDEF_UNKNOWN != chnmode)
{
nvp6158_set_chn_commonvalue( ch, chnmode );
nvp6158_video_input_new_format_set(ch, chnmode);
s_coax_str.ch = ch;
s_coax_str.fmt_def = chnmode;
nvp6158_coax_tx_init(&s_coax_str);
nvp6158_coax_tx_16bit_init(&s_coax_str); //for ahd 720P and CVI 4M
nvp6158_coax_rx_init(&s_coax_str);
vin_eq_set.Ch = ch%4;
vin_eq_set.devnum = ch/4;
vin_eq_set.distance = 0;
vin_eq_set.FmtDef = chnmode;
nvp6158_set_equalizer(&vin_eq_set);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xff,0x09);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x61);
msleep(35);
if(AHD20_SD_H960_2EX_Btype_PAL >= chnmode)
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x60); //for comet setting
else
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x00);
nvp6158_show_ch(ch);
}
else
{
nvp6158_hide_ch(ch);
auto_novid.ch = ch%4;
auto_novid.devnum = ch/4;
nvp6158_video_input_no_video_set(&auto_novid);
nvp6158_set_chn_ycmerge(ch, 0);
}
nvp6158_ch_mode_status[ch] = chnmode;
//nvp6158_ch_vfmt_status[ch] = chnmode%2;
printk(">>>>%s CH[%d] been setted to %2x mode\n", __func__, ch, chnmode);
}
return 0;
}
int nvp6168_set_chnmode(const unsigned char ch, const unsigned char chnmode)
{
//unsigned char tmp;
video_equalizer_info_s vin_eq_set;
video_input_novid auto_novid;
nvp6158_coax_str s_coax_str;
if(ch >= (nvp6158_cnt*4))
{
printk("func[nvp6168_set_chnmode] Channel %d is out of range!!!\n", ch);
return -1;
}
/* set video format each format */
if(chnmode < NC_VIVO_CH_FORMATDEF_MAX)
{
if(NC_VIVO_CH_FORMATDEF_UNKNOWN != chnmode)
{
nvp6158_set_chn_commonvalue( ch, chnmode );
//nvp6158_video_input_new_format_set(ch, chnmode);
s_coax_str.ch = ch;
s_coax_str.fmt_def = chnmode;
nvp6158_coax_tx_init(&s_coax_str);
nvp6158_coax_tx_16bit_init(&s_coax_str); //for ahd 720P and CVI 4M
nvp6158_coax_rx_init(&s_coax_str);
vin_eq_set.Ch = ch%4;
vin_eq_set.devnum = ch/4;
vin_eq_set.distance = 0;
vin_eq_set.FmtDef = chnmode;
nvp6168_set_equalizer(&vin_eq_set);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0xff,0x09);
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x61);
msleep(35);
if(AHD20_SD_H960_2EX_Btype_PAL >= chnmode)
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x60); //for comet setting
else
gpio_i2c_write(nvp6158_iic_addr[ch/4], 0x40+ch%4,0x00);
nvp6158_show_ch(ch);
}
else
{
nvp6158_hide_ch(ch);
auto_novid.ch = ch%4;
auto_novid.devnum = ch/4;
nvp6168_video_input_no_video_set(&auto_novid);
nvp6158_set_chn_ycmerge(ch, 0);
}
nvp6158_ch_mode_status[ch] = chnmode;
//nvp6158_ch_vfmt_status[ch] = chnmode%2;
printk(">>>>%s CH[%d] been setted to %2x mode\n", __func__, ch, chnmode);
}
return 0;
}
/*
nvp6158<EFBFBD><EFBFBD>nvp6158c<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
portsel<EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><EFBFBD>죬nvp6158cֻ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>2<EFBFBD><EFBFBD>nvp6158<EFBFBD><EFBFBD>4<EFBFBD><EFBFBD>port<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD>0~3<><33>
chip:chip select[0,1,2,3];
portsel: port select->6158c[1,2],6158[0,1,2,3];
portmode: port mode select[1mux,2mux,4mux]
chid: channel id, 1mux[0,1,2,3], 2mux[0,1], 4mux[0]
*/
/*******************************************************************************
* Description : select port
* Argurments : chip(chip select[0,1,2,3]),
* portsel(port select->6158c[1,2],6158[0,1,2,3];)
* portmode(port mode select[1mux,2mux,4mux]),
* chid(channel id, 1mux[0,1,2,3], 2mux[0,1], 4mux[0])
* Return value : 0
* Modify :
* warning :
*******************************************************************************/
int nvp6158_set_portmode(const unsigned char chip, const unsigned char portsel, const unsigned char portmode, const unsigned char chid)
{
unsigned char chipaddr = nvp6158_iic_addr[chip];
unsigned char tmp=0, tmp1=0, reg1=0, reg2=0;
if((portsel!=1) && (portsel!=2) && (nvp6158_chip_id[chip]==NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID))
{
printk("nvp6158C_set_portmode portsel[%d] error!!!\n", portsel);
//return -1;
}
switch(portmode)
{
case NVP6158_OUTMODE_1MUX_SD:
/*Output 720H/960H Single Channel data, Data Rate 37.125MHz,Pclk 37.125MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, (chid<<4)|chid);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, (chid<<4)|chid);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x86);
break;
case NVP6158_OUTMODE_1MUX_HD:
/*Output 720P/1280H/1440H Single Channel data,Data Rate 74.25MHz,Pclk 74.25MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, (chid<<4)|chid);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, (chid<<4)|chid);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x16);
break;
case NVP6158_OUTMODE_1MUX_FHD:
/*Output 720P@5060 /1080P Single Channel data,Data Rate 148.5MHz,Pclk 148.5MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, (chid<<4)|chid);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, (chid<<4)|chid);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x56); //0x40~0x5f adjust delay
break;
case NVP6158_OUTMODE_1MUX_FHD_DDR:
/*Output 720P@5060 /1080P Single Channel data,Data Rate 148.5MHz,Pclk 148.5MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, (chid<<4)|chid);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, (chid<<4)|chid);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x06); //0x00~0x3f adjust delay
break;
case NVP6158_OUTMODE_2MUX_SD:
/*Output 720H/960H 2 Channel data,Data Rate 74.25MHz,Pclk 74.25MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, chid==0?0x10:0x32);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, chid==0?0x10:0x32);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x20:0x02);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x16);
break;
case NVP6158_OUTMODE_2MUX_HD:
/*Output HD 2 Channel data,Data Rate 148.5MHz,Pclk 148.5MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, chid==0?0x10:0x32);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, chid==0?0x10:0x32);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x20:0x02);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x58);
break;
case NVP6158_OUTMODE_4MUX_SD:
/*Output 720H/960H 4 Channel data,Data Rate 148.5MHz,Pclk 148.5MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, 0x10);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, 0x32);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x80:0x08);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x58);
break;
case NVP6158_OUTMODE_4MUX_HD:
/*Output 720P 4 Channel data,Data Rate 297MHz,Pclk 297MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, 0x98);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, 0xba);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x80:0x08);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x58);
//gpio_i2c_write(chipaddr, 0xCC+portsel, 0x66); //single up
break;
case NVP6158_OUTMODE_2MUX_FHD:
/*5M_20P,5M_12P,4M_RT,4M_15P,3M_RT/NRT,FHD,3840H,HDEX 2mux mix, ,Data Rate 297MHz,Pclk 297MHz, Dual Edge.
SOC VI Port abandon some data, Realize 3840H->960H, HDEX->720P.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
#if 1
//CHANNEL 1 JUDGE
tmp = gpio_i2c_read(chipaddr, 0x81)&0x0F;
tmp1 = gpio_i2c_read(chipaddr, 0x85)&0x0F;
if(((tmp == 0x02) || (tmp == 0x03)) && (tmp1 == 0x04))
reg1 |= 0x08; //3M_RT, THEN OUTPUT 3M_CIF DATA
else if(((tmp == 0x0E) || (tmp == 0x0F)) && (tmp1 == 0x00))
reg1 |= 0x08; //4M, THEN OUTPUT 4M_CIF DATA
else if((tmp == 0x01) && (tmp1 == 0x05)) //ahd 5m20p
reg1 |= 0x08;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && ((tmp1 == 0x02) || (tmp1 == 0x03))) //tvi/cvi 4m rt
reg1 |= 0x08;
else if(((tmp == 0x01) || (tmp == 0x02)) && ((tmp1 == 0x08) || (tmp1 == 0x09) || (tmp1 == 0x0a))) //8M
reg1 |= 0x08;
else
reg1 &= 0xF0;
//CHANNEL 2 JUDGE
tmp = gpio_i2c_read(chipaddr, 0x82)&0x0F;
tmp1 = gpio_i2c_read(chipaddr, 0x86)&0x0F;
if(((tmp == 0x02) || (tmp == 0x03)) && (tmp1 == 0x04))
reg1 |= 0x80;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && (tmp1 == 0x00))
reg1 |= 0x80;
else if((tmp == 0x01) && (tmp1 == 0x05))
reg1 |= 0x80;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && ((tmp1 == 0x02) || (tmp1 == 0x03))) //tvi/cvi 4m rt
reg1 |= 0x80;
else if(((tmp == 0x01) || (tmp == 0x02)) && ((tmp1 == 0x08) || (tmp1 == 0x09) ||(tmp1 == 0x0a))) //8M
reg1 |= 0x80;
else
reg1 &= 0x0F;
//CHANNEL 3 JUDGE
tmp = gpio_i2c_read(chipaddr, 0x83)&0x0F;
tmp1 = gpio_i2c_read(chipaddr, 0x87)&0x0F;
if(((tmp == 0x02) || (tmp == 0x03)) && (tmp1 == 0x04))
reg2 |= 0x08;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && (tmp1 == 0x00))
reg2 |= 0x08;
else if((tmp == 0x01) && (tmp1 == 0x05))
reg2 |= 0x08;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && ((tmp1 == 0x02) || (tmp1 == 0x03))) //tvi/cvi 4m rt
reg2 |= 0x08;
else if(((tmp == 0x01) || (tmp == 0x02)) && ((tmp1 == 0x08) || (tmp1 == 0x09) ||(tmp1 == 0x0a))) //8M
reg2 |= 0x08;
else
reg2 &= 0xF0;
//CHANNEL 4 JUDGE
tmp = gpio_i2c_read(chipaddr, 0x84)&0x0F;
tmp1 = gpio_i2c_read(chipaddr, 0x88)&0x0F;
if(((tmp == 0x02) || (tmp == 0x03)) && (tmp1 == 0x04))
reg2 |= 0x80;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && (tmp1 == 0x00))
reg2 |= 0x80;
else if((tmp == 0x01) && (tmp1 == 0x05))
reg2 |= 0x80;
else if(((tmp == 0x0E) || (tmp == 0x0F)) && ((tmp1 == 0x02) || (tmp1 == 0x03))) //tvi/cvi 4m rt
reg2 |= 0x80;
else if(((tmp == 0x01) || (tmp == 0x02)) && ((tmp1 == 0x08) || (tmp1 == 0x09) ||(tmp1 == 0x0a))) //ahd 8M
reg2 |= 0x80;
else
reg2 &= 0x0F;
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, chid==0?(0x10|reg1):(0x32|reg2));
gpio_i2c_write(chipaddr, 0xC1+portsel*2, chid==0?(0x10|reg1):(0x32|reg2));
#else
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, chid==0?0x10:0x32);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, chid==0?0x10:0x32);
#endif
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x20:0x02);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x56);
//gpio_i2c_write(chipaddr, 0xCC+portsel, 0x66); //single up
break;
case NVP6158_OUTMODE_4MUX_MIX:
/*HD,1920H,FHD-X 4mux mix,Data Rate 297MHz,Pclk 297MHz, Dual Edge.
SOC VI Port Abandon some data<74><61>realize 1920H->960H */
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, 0x98);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, 0xba);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x80:0x08);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x58);
//gpio_i2c_write(chipaddr, 0xCC+portsel, 0x66); //single up
break;
case NVP6158_OUTMODE_2MUX_MIX:
/*HD,1920H,FHD-X 2mux mix,Data Rate 148.5MHz,Pclk 148.5MHz, Single Edge.
SOC VI Port Abandon some data, realize 1920H->960H */
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, chid==0?0x98:0xba);
gpio_i2c_write(chipaddr, 0xC1+portsel*2, chid==0?0x98:0xba);
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
tmp |= (portsel%2?0x20:0x02);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x58);
break;
case NVP6158_OUTMODE_1MUX_BT1120S_720P:
/*Output 720P Single Channel data,Data Rate 37.125MHz,Pclk 37.125MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC3, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC5, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC8, 0x00);
gpio_i2c_write(chipaddr, 0xC9, 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x86); //37.125MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC1+portsel*4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC2+portsel*4, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC3+portsel*4, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x86); //37.125MHz clock
}
break;
case NVP6158_OUTMODE_1MUX_BT1120S_1080P:
/*Output 1080 Single Channel data,Data Rate 74.25MHz,Pclk 74.25MHz, Single Edge.*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC3, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC5, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC8, 0x00);
gpio_i2c_write(chipaddr, 0xC9, 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x06); //74.25MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC1+portsel*4, (((chid%4)+0x0C)<<4)|((chid%4)+0x0C));
gpio_i2c_write(chipaddr, 0xC2+portsel*4, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC3+portsel*4, (((chid%4)+0x04)<<4)|((chid%4)+0x04));
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x86); //37.125MHz clock
}
break;
case NVP6158_OUTMODE_2MUX_BT1120S:
case NVP6158_OUTMODE_2MUX_BT1120S_720P:
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, 0xdc);
gpio_i2c_write(chipaddr, 0xC3, 0xdc);
gpio_i2c_write(chipaddr, 0xC4, 0x54);
gpio_i2c_write(chipaddr, 0xC5, 0x54);
gpio_i2c_write(chipaddr, 0xC8, 0x22);
gpio_i2c_write(chipaddr, 0xC9, 0x22);
gpio_i2c_write(chipaddr, 0xCD, 0x1f); //74.25MHz clock
gpio_i2c_write(chipaddr, 0xCE, 0x1f); //74.25MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC1+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC2+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC3+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x06); //74.25MHz clock
}
break;
case NVP6158_OUTMODE_2MUX_BT1120S_1080P:
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, 0x54);
gpio_i2c_write(chipaddr, 0xC3, 0x54);
gpio_i2c_write(chipaddr, 0xC4, 0xdc);
gpio_i2c_write(chipaddr, 0xC5, 0xdc);
gpio_i2c_write(chipaddr, 0xC8, 0x22);
gpio_i2c_write(chipaddr, 0xC9, 0x22);
gpio_i2c_write(chipaddr, 0xCD, 0x56); //148.5MHz clock
gpio_i2c_write(chipaddr, 0xCE, 0x56); //148.5MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC1+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC2+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC3+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x00);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x06); //74.25MHz clock
}
break;
case NVP6158_OUTMODE_4MUX_BT1120S:
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if (nvp6158_chip_id[chip] == NVP6158C_R0_ID ||
nvp6158_chip_id[chip] == NVP6168C_R0_ID) {
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, 0x54);
gpio_i2c_write(chipaddr, 0xC3, 0x76);
gpio_i2c_write(chipaddr, 0xC4, 0xdc);
gpio_i2c_write(chipaddr, 0xC5, 0xfe);
gpio_i2c_write(chipaddr, 0xC8, 0x88);
gpio_i2c_write(chipaddr, 0xC9, 0x88);
//single edge
gpio_i2c_write(chipaddr, 0xCD, 0x46); //148.5MHz clock
gpio_i2c_write(chipaddr, 0xCE, 0x46); //148.5MHz clock
// //dual_edge
// gpio_i2c_write(chipaddr, 0xCD, 0x06); //74.25MHz clock
// gpio_i2c_write(chipaddr, 0xCE, 0x06); //74.25MHz clock
} else {
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC1+portsel*4, 0xfe);
gpio_i2c_write(chipaddr, 0xC2+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC3+portsel*4, 0x76);
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x88);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x58); //148.5MHz clock
}
break;
case NVP6158_OUTMODE_4MUX_BT1120S_DDR:
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, 0x54);
gpio_i2c_write(chipaddr, 0xC3, 0x76);
gpio_i2c_write(chipaddr, 0xC4, 0xdc);
gpio_i2c_write(chipaddr, 0xC5, 0xfe);
gpio_i2c_write(chipaddr, 0xC8, 0x88);
gpio_i2c_write(chipaddr, 0xC9, 0x88);
//dual_edge
gpio_i2c_write(chipaddr, 0xCD, 0x06); //74.25MHz clock
gpio_i2c_write(chipaddr, 0xCE, 0x06); //74.25MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC1+portsel*4, 0xfe);
gpio_i2c_write(chipaddr, 0xC2+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC3+portsel*4, 0x76);
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x88);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x58); //148.5MHz clock
}
break;
case NVP6158_OUTMODE_4MUX_BT1120S_1080P:
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x32);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
//6158C makes 2 bt656 ports to 1 bt1120 port. portsel=[1,2] to choose clock.
gpio_i2c_write(chipaddr, 0xC2, 0x54);
gpio_i2c_write(chipaddr, 0xC3, 0x76);
gpio_i2c_write(chipaddr, 0xC4, 0xdc);
gpio_i2c_write(chipaddr, 0xC5, 0xfe);
gpio_i2c_write(chipaddr, 0xC8, 0x88);
gpio_i2c_write(chipaddr, 0xC9, 0x88);
gpio_i2c_write(chipaddr, 0xCD, 0x40); //148.5MHz clock
gpio_i2c_write(chipaddr, 0xCE, 0x40); //148.5MHz clock
}
else
{
//6158 makes 4 bt656 ports to 2 bt1120 port. portsel=[0,1] to choose clock.
gpio_i2c_write(chipaddr, 0xC0+portsel*4, 0xdc);
gpio_i2c_write(chipaddr, 0xC1+portsel*4, 0xfe);
gpio_i2c_write(chipaddr, 0xC2+portsel*4, 0x54);
gpio_i2c_write(chipaddr, 0xC3+portsel*4, 0x76);
gpio_i2c_write(chipaddr, 0xC8+(portsel), 0x88);
gpio_i2c_write(chipaddr, 0xCC+portsel*2, 0x58); //148.5MHz clock
}
break;
case NVP6158_OUTMODE_1MUX_297MHz:
/*1MUX data output, Pclk 297MHZ*/
gpio_i2c_write(chipaddr, 0xFF, 0x00);
gpio_i2c_write(chipaddr, 0x56, 0x10);
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xC0+portsel*2, (chid<<4)|chid); /* Port selection */
gpio_i2c_write(chipaddr, 0xC1+portsel*2, (chid<<4)|chid); /* Port selection */
tmp = gpio_i2c_read(chipaddr, 0xC8+(portsel/2)) & (portsel%2?0x0F:0xF0);
gpio_i2c_write(chipaddr, 0xC8+(portsel/2), tmp);
gpio_i2c_write(chipaddr, 0xCC+portsel, 0x66);
break;
default:
printk("portmode %d not supported yet\n", portmode);
break;
}
printk("nvp6158(b)_set_portmode portsel %d portmode %d setting\n", portsel, portmode);
if(portmode==NVP6158_OUTMODE_2MUX_SD ||\
portmode==NVP6158_OUTMODE_4MUX_SD ||\
portmode==NVP6158_OUTMODE_2MUX_HD ||\
portmode==NVP6158_OUTMODE_2MUX_MIX ||\
portmode==NVP6158_OUTMODE_2MUX_BT1120S ||\
portmode==NVP6158_OUTMODE_2MUX_BT1120S_720P ||\
portmode==NVP6158_OUTMODE_2MUX_BT1120S_1080P ||\
portmode==NVP6158_OUTMODE_4MUX_BT1120S)
{
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xA0+portsel, 0x20); //TM clock mode sel manual
printk("TM clock mode sel manual mode \n");
}
else
{
gpio_i2c_write(chipaddr, 0xFF, 0x01);
gpio_i2c_write(chipaddr, 0xA0+portsel, 0x00); //TM clock mode sel auto
printk("TM clock mode sel auto mode \n");
}
return 0;
}
/*
chip:0~3
portsel: 6158b/c->1/2, 6158->0~3
enclk: enable clock pin, 1:enable,0:disable;
endata: enable data port, 1:enable,0:disable;
*/
void nvp6158_set_portcontrol(const unsigned char chip, const unsigned char portsel, const unsigned char enclk, const unsigned char endata)
{
unsigned char reg_portctl;
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
reg_portctl = gpio_i2c_read(nvp6158_iic_addr[chip], 0xCA);
if(nvp6158_chip_id[chip] == NVP6158C_R0_ID || nvp6158_chip_id[chip] == NVP6168C_R0_ID)
{
if(enclk == 1)
_SET_BIT(reg_portctl, (portsel+5));
else
_CLE_BIT(reg_portctl, (portsel+5));
if(endata == 1)
_SET_BIT(reg_portctl, portsel);
else
_CLE_BIT(reg_portctl, portsel);
}
else if(nvp6158_chip_id[chip] == NVP6158_R0_ID)
{
if(enclk == 1)
_SET_BIT(reg_portctl, (portsel+4));
else
_CLE_BIT(reg_portctl, (portsel+4));
if(endata == 1)
_SET_BIT(reg_portctl, portsel);
else
_CLE_BIT(reg_portctl, portsel);
}
}
NC_FORMAT_STANDARD NVP6158_GetFmtStd_from_Fmtdef(NC_VIVO_CH_FORMATDEF vivofmt)
{
NC_FORMAT_STANDARD vformat_std= FMT_STD_UNKNOWN;
if((vivofmt>=AHD20_SD_H960_NT) && (vivofmt<=AHD20_SD_H960_2EX_Btype_PAL))
vformat_std = FMT_SD;
else if((vivofmt>=CVI_FHD_30P) && (vivofmt<=CVI_8M_12_5P))
vformat_std = FMT_CVI;
else if((vivofmt>=TVI_FHD_30P) && (vivofmt<=TVI_8M_12_5P))
vformat_std = FMT_TVI;
else if((vivofmt>=AHD20_1080P_60P) && (vivofmt<=AHD20_720P_25P_EX_Btype))
vformat_std = FMT_AHD20;
else if((vivofmt>=AHD30_4M_30P) && (vivofmt<=AHD30_8M_15P))
vformat_std = FMT_AHD30;
else
vformat_std = FMT_STD_UNKNOWN;
return vformat_std;
}
void nvp6158_additional_for3MoverDef(unsigned char chip)
{
unsigned char ch = 0;
for(ch = 0; ch < 4; ch++)
{
gpio_i2c_write(nvp6158_iic_addr[chip], 0xff, 0x0a + (ch / 2));
gpio_i2c_write(nvp6158_iic_addr[chip], 0x00 + ( 0x80 * (ch % 2)), 0x80 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x01 + ( 0x80 * (ch % 2)), 0x02 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x02 + ( 0x80 * (ch % 2)), 0x04 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x03 + ( 0x80 * (ch % 2)), 0x80 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x04 + ( 0x80 * (ch % 2)), 0x06 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x05 + ( 0x80 * (ch % 2)), 0x07 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x06 + ( 0x80 * (ch % 2)), 0x80 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x07 + ( 0x80 * (ch % 2)), 0x07 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x08 + ( 0x80 * (ch % 2)), 0x03 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x09 + ( 0x80 * (ch % 2)), 0x08 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0a + ( 0x80 * (ch % 2)), 0x04 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0b + ( 0x80 * (ch % 2)), 0x10 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0c + ( 0x80 * (ch % 2)), 0x08 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0d + ( 0x80 * (ch % 2)), 0x1f );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0e + ( 0x80 * (ch % 2)), 0x2e );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x0f + ( 0x80 * (ch % 2)), 0x08 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x10 + ( 0x80 * (ch % 2)), 0x38 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x11 + ( 0x80 * (ch % 2)), 0x35 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x12 + ( 0x80 * (ch % 2)), 0x00 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x13 + ( 0x80 * (ch % 2)), 0x20 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x14 + ( 0x80 * (ch % 2)), 0x0d );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x15 + ( 0x80 * (ch % 2)), 0x80 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x16 + ( 0x80 * (ch % 2)), 0x54 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x17 + ( 0x80 * (ch % 2)), 0xb1 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x18 + ( 0x80 * (ch % 2)), 0x91 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x19 + ( 0x80 * (ch % 2)), 0x1c );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1a + ( 0x80 * (ch % 2)), 0x87 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1b + ( 0x80 * (ch % 2)), 0x92 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1c + ( 0x80 * (ch % 2)), 0xe2 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1d + ( 0x80 * (ch % 2)), 0x20 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1e + ( 0x80 * (ch % 2)), 0xd0 );
gpio_i2c_write(nvp6158_iic_addr[chip], 0x1f + ( 0x80 * (ch % 2)), 0xcc );
}
}
void nvp6158_video_powerdown(unsigned char ch)
{
unsigned char val_0x00; //video afe;
unsigned char val_1x97; //clock;
unsigned char val_1x98; //channel;
unsigned char chip = ch / 4;
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x00);
val_0x00 = gpio_i2c_read(nvp6158_iic_addr[chip], 0x00+(ch%4));
gpio_i2c_write(nvp6158_iic_addr[chip], 0x00+(ch%4), (val_0x00|0x01));
gpio_i2c_write(nvp6158_iic_addr[chip], 0xFF, 0x01);
val_1x97 = gpio_i2c_read(nvp6158_iic_addr[chip], 0x97);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x97, (val_1x97&(~(0x01<<(ch%4)))));
val_1x98 = gpio_i2c_read(nvp6158_iic_addr[chip], 0x98);
gpio_i2c_write(nvp6158_iic_addr[chip], 0x98, (val_1x98|(0x01<<(ch%4))));
printk(">>>>%s CH[%d] been setted to powerdown mode\n", __func__, ch);
}
/********************************************************************************
* End of file
********************************************************************************/