⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vt1622a.c

📁 VIA Framebuffer driver
💻 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 + -