📄 vt1622a.c
字号:
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <linux/ioport.h>
#include <asm/io.h>
//#include "viamode.h"
#include "tv.h"
#include "tbl1622a.h"
#include "share.h"
#include "chip.h"
#include "debug.h"
extern inline void lock_crt(void);
extern inline void unlock_crt(void);
extern inline void write_reg(u8 index, u16 io_port, u8 data);
extern void write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
extern void load_crtc_timing(struct display_timing device_timing, int set_iga);
extern void load_tv_output_signal(u16 *tv_func_reg);
extern struct tv_setting_information tv_setting_info;
int vt1622a_map_tv_func(int out_signal);
int vt1622a_tv_encoder_identify(void)
{
int ver;
ver = tv_register_read(VT1622A_VERSION_REG);
DEBUG_MSG(KERN_INFO "\n\nVT1622A Version=%2d", ver);
if (ver == VT1622A_VERSION)
{
DEBUG_MSG(KERN_INFO "\nFind VT1622A TV Encoder \n");
return(OK);
}
else
return(FAIL);
}
void vt1622a_tv_disable(void)
{
// turn off TV's DAC
tv_register_write(0x0e, 0x0f);
}
void load_vt1622a_regs(int TVModeIndex)
{
int i, index;
u8 tmp;
vt1622a_func_table *vt1622a_func;
struct display_timing tv_crtc_reg;
u16 *tv_reg=NULL;
u16 *tv_func_reg=NULL;
for(i=0;i<NUM_TOTAL_VT1622A_TABLE;i++)
{
index = i;
if (vt1622a_tbl[i].tv_index == TVModeIndex)
break;
}
if (tv_setting_info.system == NTSC)
vt1622a_func = vt1622a_tbl[index].tv_mode_ntsc;
else
vt1622a_func = vt1622a_tbl[index].tv_mode_pal;
if (tv_setting_info.level == 0)
tv_reg = vt1622a_func[0].tv_underscan;
if (tv_setting_info.level == 1)
tv_reg = vt1622a_func[0].tv_fitscan;
if (tv_setting_info.level == 2)
tv_reg = vt1622a_func[0].tv_overscan;
// unlock CRTC Register
unlock_crt();
// update starting address
write_reg(CR0C, VIACR, 0x00);
write_reg(CR0D, VIACR, 0x00);
//write_reg(CR34, VIACR, 0x00);
write_reg_mask(CR48, VIACR, 0x00, BIT0+BIT1);
write_reg(CR62, VIACR, 0x00);
write_reg(CR63, VIACR, 0x00);
write_reg(CR64, VIACR, 0x00);
// Load TV Encoder Regsiters
for (i=0;i<NUM_TOTAL_VT1622A_REG;i++)
{
tv_register_write(GET_LOW_BYTE(tv_reg[i]),GET_HIGH_BYTE(tv_reg[i]));
}
// Load GFX CRTC timing when TV work on IGA1
for (i=0; i< NUM_CRTC_TIMING; i++)
{
switch(i) {
case H_TOTAL_INDEX:
tv_crtc_reg.hor_total = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case H_ADDR_INDEX:
tv_crtc_reg.hor_addr = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case H_BLANK_SATRT_INDEX:
tv_crtc_reg.hor_blank_start = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case H_BLANK_END_INDEX:
tv_crtc_reg.hor_blank_end = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case H_SYNC_SATRT_INDEX:
tv_crtc_reg.hor_sync_start = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case H_SYNC_END_INDEX:
tv_crtc_reg.hor_sync_end = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_TOTAL_INDEX:
tv_crtc_reg.ver_total = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_ADDR_INDEX:
tv_crtc_reg.ver_addr = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_BLANK_SATRT_INDEX:
tv_crtc_reg.ver_blank_start = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_BLANK_END_INDEX:
tv_crtc_reg.ver_blank_end = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_SYNC_SATRT_INDEX:
tv_crtc_reg.ver_sync_start = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
case V_SYNC_END_INDEX:
tv_crtc_reg.ver_sync_end = tv_reg[i+NUM_TOTAL_VT1622A_REG];
break;
}
}
if ( tv_setting_info.iga_path == IGA1)
load_crtc_timing(tv_crtc_reg, IGA1);
else
{
load_crtc_timing(tv_crtc_reg, IGA2);
write_reg(CR65, VIACR, 0x80);
write_reg(CR66, VIACR, 0x00);
write_reg(CR67, VIACR, 0x41);
//oad_offset_reg(h_addr, bpp_byte, IGA2);
//load_fetch_count_reg(h_addr, bpp_byte, IGA2);
}
DEBUG_MSG(KERN_INFO "\n tv_out_signal = %2d \n", tv_setting_info.out_signal);
DEBUG_MSG(KERN_INFO "\nVT1622A_MAP_TV = %2d \n", vt1622a_map_tv_func(tv_setting_info.out_signal));
index = vt1622a_map_tv_func(tv_setting_info.out_signal);
if (index != 0)
{
DEBUG_MSG(KERN_INFO "\nVT1622_MAP_TV = %2d\n", VT1622A);
if (tv_setting_info.level == 0)
tv_func_reg = vt1622a_func[index].tv_underscan;
if (tv_setting_info.level == 1)
tv_func_reg = vt1622a_func[index].tv_fitscan;
if (tv_setting_info.level == 2)
tv_func_reg = vt1622a_func[index].tv_overscan;
load_tv_output_signal(tv_func_reg);
}
if ((tv_setting_info.dedotcrawl == 1) && (tv_setting_info.out_signal==TV_OUTPUT_COMPOSITE) && (tv_setting_info.system == NTSC))
{
index = vt1622a_map_tv_func(TV_OUTPUT_DEDOTCRAWL);
if (index != 0)
{
if (tv_setting_info.level == 0)
tv_func_reg = vt1622a_func[index].tv_underscan;
if (tv_setting_info.level == 1)
tv_func_reg = vt1622a_func[index].tv_fitscan;
if (tv_setting_info.level == 2)
tv_func_reg = vt1622a_func[index].tv_overscan;
tmp = (u8) tv_register_read(VT1622A_DEDOTCRAWL_REG);
tv_register_write(VT1622A_DEDOTCRAWL_REG, tmp | BIT3);
load_tv_output_signal(tv_func_reg);
}
}
lock_crt();
}
void vt1622a_tv_enable(void)
{
u8 data;
data = (u8)tv_register_read(VT1622A_DAC_REG);
// turn on TV's DAC
switch(tv_setting_info.out_signal) {
case TV_OUTPUT_COMPOSITE:
data = (data & 0xF0)|((~VT1622A_DAC_A)&0x0F);
break;
case TV_OUTPUT_SVIDEO:
data = (data & 0xF0)|((~(VT1622A_DAC_A+VT1622A_DAC_B))&0x0F);
case TV_OUTPUT_COMPOSITE_SVIDEO:
data = (data & 0xF0)|((~(VT1622A_DAC_A+VT1622A_DAC_B+VT1622A_DAC_C))&0x0F);
break;
case TV_OUTPUT_RGB:
case TV_OUTPUT_RGB_COMPOSITE:
case TV_OUTPUT_SDTV_PROGRESSIVE_RGB:
case TV_OUTPUT_HDTV_720P_RGB:
case TV_OUTPUT_HDTV_1080I_RGB:
case TV_OUTPUT_HDTV_1080P_RGB:
case TV_OUTPUT_YPBPR_COMPOSITE:
data = (data & 0xF0)|((~(VT1622A_DAC_A+VT1622A_DAC_B+VT1622A_DAC_C+VT1622A_DAC_D))&0x0F);
break;
case TV_OUTPUT_YPBPR:
case TV_OUTPUT_SDTV_PROGRESSIVE_YPBPR:
case TV_OUTPUT_HDTV_720P_YPBPR:
case TV_OUTPUT_HDTV_1080I_YPBPR:
case TV_OUTPUT_HDTV_1080P_YPBPR:
data = (data & 0xF0)|((~(VT1622A_DAC_B+VT1622A_DAC_C+VT1622A_DAC_D))&0x0F);
break;
default:
data = (data & 0xF0)|((~(VT1622A_DAC_B+VT1622A_DAC_C+VT1622A_DAC_D))&0x0F);
}
tv_register_write(VT1622A_DAC_REG, data);
}
int vt1622a_map_tv_func(int out_signal)
{
int tv_func_index;
switch(out_signal) {
case TV_OUTPUT_COMPOSITE:
case TV_OUTPUT_SVIDEO:
case TV_OUTPUT_COMPOSITE_SVIDEO:
tv_func_index = 0;
break;
case TV_OUTPUT_RGB:
tv_func_index = TV_RGB_FUNC;
break;
case TV_OUTPUT_YPBPR:
tv_func_index = TV_YPBPR_FUNC;
break;
case TV_OUTPUT_SDTV_PROGRESSIVE_RGB:
tv_func_index = TV_SDTV_RGB_FUNC;
break;
case TV_OUTPUT_SDTV_PROGRESSIVE_YPBPR:
tv_func_index = TV_SDTV_YPBPR_FUNC;
break;
case TV_OUTPUT_DEDOTCRAWL:
tv_func_index = TV_DeDotCrawl_FUNC;
break;
case TV_OUTPUT_HDTV_720P_RGB:
case TV_OUTPUT_HDTV_720P_YPBPR:
case TV_OUTPUT_HDTV_1080I_RGB:
case TV_OUTPUT_HDTV_1080I_YPBPR:
case TV_OUTPUT_HDTV_1080P_RGB:
case TV_OUTPUT_HDTV_1080P_YPBPR:
tv_func_index = 0;
break;
default:
tv_func_index = 0;
}
return(tv_func_index);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -