📄 sisusb_init.c
字号:
/* * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles * * Display mode initializing code * * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria * * If distributed as part of the Linux kernel, this code is licensed under the * terms of the GPL v2. * * Otherwise, the following license terms apply: * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * 1) Redistributions of source code must retain the above copyright * * notice, this list of conditions and the following disclaimer. * * 2) Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * 3) The name of the author may not be used to endorse or promote products * * derived from this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Author: Thomas Winischhofer <thomas@winischhofer.net> * */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/poll.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <linux/kref.h>#include "sisusb.h"#ifdef INCL_SISUSB_CON#include "sisusb_init.h"/*********************************************//* POINTER INITIALIZATION *//*********************************************/static voidSiSUSB_InitPtr(struct SiS_Private *SiS_Pr){ SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; SiS_Pr->SiS_StandTable = SiSUSB_StandTable; SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData;}/*********************************************//* HELPER: Get ModeID *//*********************************************/unsigned shortSiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth){ unsigned short ModeIndex = 0; switch (HDisplay) { case 320: if (VDisplay == 200) ModeIndex = ModeIndex_320x200[Depth]; else if (VDisplay == 240) ModeIndex = ModeIndex_320x240[Depth]; break; case 400: if (VDisplay == 300) ModeIndex = ModeIndex_400x300[Depth]; break; case 512: if (VDisplay == 384) ModeIndex = ModeIndex_512x384[Depth]; break; case 640: if (VDisplay == 480) ModeIndex = ModeIndex_640x480[Depth]; else if (VDisplay == 400) ModeIndex = ModeIndex_640x400[Depth]; break; case 720: if (VDisplay == 480) ModeIndex = ModeIndex_720x480[Depth]; else if (VDisplay == 576) ModeIndex = ModeIndex_720x576[Depth]; break; case 768: if (VDisplay == 576) ModeIndex = ModeIndex_768x576[Depth]; break; case 800: if (VDisplay == 600) ModeIndex = ModeIndex_800x600[Depth]; else if (VDisplay == 480) ModeIndex = ModeIndex_800x480[Depth]; break; case 848: if (VDisplay == 480) ModeIndex = ModeIndex_848x480[Depth]; break; case 856: if (VDisplay == 480) ModeIndex = ModeIndex_856x480[Depth]; break; case 960: if (VDisplay == 540) ModeIndex = ModeIndex_960x540[Depth]; else if (VDisplay == 600) ModeIndex = ModeIndex_960x600[Depth]; break; case 1024: if (VDisplay == 576) ModeIndex = ModeIndex_1024x576[Depth]; else if (VDisplay == 768) ModeIndex = ModeIndex_1024x768[Depth]; break; case 1152: if (VDisplay == 864) ModeIndex = ModeIndex_1152x864[Depth]; break; case 1280: switch (VDisplay) { case 720: ModeIndex = ModeIndex_1280x720[Depth]; break; case 768: ModeIndex = ModeIndex_1280x768[Depth]; break; case 1024: ModeIndex = ModeIndex_1280x1024[Depth]; break; } } return ModeIndex;}/*********************************************//* HELPER: SetReg, GetReg *//*********************************************/static voidSiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index, unsigned short data){ sisusb_setidxreg(SiS_Pr->sisusb, port, index, data);}static voidSiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short data){ sisusb_setreg(SiS_Pr->sisusb, port, data);}static unsigned charSiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index){ u8 data; sisusb_getidxreg(SiS_Pr->sisusb, port, index, &data); return data;}static unsigned charSiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port){ u8 data; sisusb_getreg(SiS_Pr->sisusb, port, &data); return data;}static voidSiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index, unsigned short DataAND, unsigned short DataOR){ sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR);}static voidSiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index, unsigned short DataAND){ sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND);}static voidSiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, unsigned short index, unsigned short DataOR){ sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR);}/*********************************************//* HELPER: DisplayOn, DisplayOff *//*********************************************/static voidSiS_DisplayOn(struct SiS_Private *SiS_Pr){ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF);}/*********************************************//* HELPER: Init Port Addresses *//*********************************************/voidSiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr){ SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; SiS_Pr->SiS_P3c0 = BaseAddr + 0x10; SiS_Pr->SiS_P3ce = BaseAddr + 0x1e; SiS_Pr->SiS_P3c2 = BaseAddr + 0x12; SiS_Pr->SiS_P3ca = BaseAddr + 0x1a; SiS_Pr->SiS_P3c6 = BaseAddr + 0x16; SiS_Pr->SiS_P3c7 = BaseAddr + 0x17; SiS_Pr->SiS_P3c8 = BaseAddr + 0x18; SiS_Pr->SiS_P3c9 = BaseAddr + 0x19; SiS_Pr->SiS_P3cb = BaseAddr + 0x1b; SiS_Pr->SiS_P3cc = BaseAddr + 0x1c; SiS_Pr->SiS_P3cd = BaseAddr + 0x1d; SiS_Pr->SiS_P3da = BaseAddr + 0x2a; SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;}/*********************************************//* HELPER: GetSysFlags *//*********************************************/static voidSiS_GetSysFlags(struct SiS_Private *SiS_Pr){ SiS_Pr->SiS_MyCR63 = 0x63;}/*********************************************//* HELPER: Init PCI & Engines *//*********************************************/static voidSiSInitPCIetc(struct SiS_Private *SiS_Pr){ SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); /* - Enable 2D (0x40) * - Enable 3D (0x02) * - Enable 3D vertex command fetch (0x10) * - Enable 3D command parser (0x08) * - Enable 3D G/L transformation engine (0x80) */ SiS_SetRegOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1E, 0xDA);}/*********************************************//* HELPER: SET SEGMENT REGISTERS *//*********************************************/static voidSiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp; value &= 0x00ff; temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0xf0; temp |= (value >> 4); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0xf0; temp |= (value & 0x0f); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);}static voidSiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp; value &= 0x00ff; temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb) & 0x0f; temp |= (value & 0xf0); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cb, temp); temp = SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd) & 0x0f; temp |= (value << 4); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp);}static voidSiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value){ SiS_SetSegRegLower(SiS_Pr, value); SiS_SetSegRegUpper(SiS_Pr, value);}static voidSiS_ResetSegmentReg(struct SiS_Private *SiS_Pr){ SiS_SetSegmentReg(SiS_Pr, 0);}static voidSiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value){ unsigned short temp = value >> 8; temp &= 0x07; temp |= (temp << 4); SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x1d, temp); SiS_SetSegmentReg(SiS_Pr, value);}static voidSiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr){ SiS_SetSegmentRegOver(SiS_Pr, 0);}static voidSiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr){ SiS_ResetSegmentReg(SiS_Pr); SiS_ResetSegmentRegOver(SiS_Pr);}/*********************************************//* HELPER: SearchModeID *//*********************************************/static intSiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, unsigned short *ModeIdIndex){ if ((*ModeNo) <= 0x13) { if ((*ModeNo) != 0x03) return 0; (*ModeIdIndex) = 0; } else { for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break; if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) return 0; } } return 1;}/*********************************************//* HELPER: ENABLE CRT1 *//*********************************************/static voidSiS_HandleCRT1(struct SiS_Private *SiS_Pr){ /* Enable CRT1 gating */ SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf);}/*********************************************//* HELPER: GetColorDepth *//*********************************************/static unsigned shortSiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex){ static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; unsigned short modeflag; short index; if (ModeNo <= 0x13) { modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag; } else { modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; } index = (modeflag & ModeTypeMask) - ModeEGA; if (index < 0) index = 0; return ColorDepth[index];}/*********************************************//* HELPER: GetOffset *//*********************************************/static unsigned shortSiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short ModeIdIndex, unsigned short rrti){ unsigned short xres, temp, colordepth, infoflag; infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; xres = SiS_Pr->SiS_RefIndex[rrti].XRes; colordepth = SiS_GetColorDepth(SiS_Pr, ModeNo, ModeIdIndex); temp = xres / 16; if (infoflag & InterlaceMode) temp <<= 1; temp *= colordepth; if (xres % 16) temp += (colordepth >> 1); return temp;}/*********************************************//* SEQ *//*********************************************/static voidSiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex){ unsigned char SRdata; int i; SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x00, 0x03); SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); for(i = 2; i <= 4; i++) { SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); }}/*********************************************//* MISC *//*********************************************/static voidSiS_SetMiscRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex){ unsigned char Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC; SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c2, Miscdata);}/*********************************************//* CRTC *//*********************************************/static voidSiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex){ unsigned char CRTCdata; unsigned short i; SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); for(i = 0; i <= 0x18; i++) { CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); }}/*********************************************//* ATT *//*********************************************/static voidSiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex){ unsigned char ARdata; unsigned short i; for(i = 0; i <= 0x13; i++) { ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, ARdata); } SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x14); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x00); SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, 0x20); SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da);}/*********************************************//* GRC *//*********************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -