diff options
author | Luc Verhaegen <libv@skynet.be> | 2005-10-13 18:21:26 +0000 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2005-10-13 18:21:26 +0000 |
commit | 250ff89aebc1750b3d547b0930a6c2323b5fe669 (patch) | |
tree | 6dcdd27f04141685c88254ee0c2fdd7714b0bb3b | |
parent | e0a847e05582bca43e36ece718fe9ef94f1bb59b (diff) |
[devel-add_ch7011] Add support for the Chrontel CH7011, as found on the
shuttle FX43.
-rw-r--r-- | src/Imakefile | 4 | ||||
-rw-r--r-- | src/via_bios.h | 16 | ||||
-rw-r--r-- | src/via_ch7xxx.c | 445 | ||||
-rw-r--r-- | src/via_ch7xxx.h | 149 | ||||
-rw-r--r-- | src/via_mode.c | 19 |
5 files changed, 624 insertions, 9 deletions
diff --git a/src/Imakefile b/src/Imakefile index effc8d3..02866da 100644 --- a/src/Imakefile +++ b/src/Imakefile @@ -93,6 +93,7 @@ SRCS = via_driver.c \ via_memory.c \ via_vgahw.c \ via_vt162x.c \ + via_ch7xxx.c \ $(DRISRCS) OBJS = via_driver.o \ @@ -108,6 +109,7 @@ OBJS = via_driver.o \ via_memory.o \ via_vgahw.o \ via_vt162x.o \ + via_ch7xxx.o \ $(DRIOBJS) #if defined(XF86DriverSDK) @@ -154,6 +156,8 @@ InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_accel.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_bandwidth.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_bios.h,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_ch7xxx.c,$(DRIVERSDKDIR)/drivers/via) +InstallDriverSDKNonExecFile(via_ch7xxx.h,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_cursor.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_dga.c,$(DRIVERSDKDIR)/drivers/via) InstallDriverSDKNonExecFile(via_dri.c,$(DRIVERSDKDIR)/drivers/via) diff --git a/src/via_bios.h b/src/via_bios.h index 3bbdb1e..e3d96e0 100644 --- a/src/via_bios.h +++ b/src/via_bios.h @@ -46,11 +46,13 @@ #define TVOUTPUT_YCBCR 0x08 #define TVOUTPUT_SC 0x16 -#define VIA_NONETV 0 -#define VIA_VT1621 1 /* TV2PLUS */ -#define VIA_VT1622 2 /* TV3 */ -#define VIA_VT1623 3 /* also VT1622A */ -#define VIA_VT1625 4 +#define VIA_NONETV 0x00 +#define VIA_VT1621 0x01 /* TV2PLUS */ +#define VIA_VT1622 0x02 /* TV3 */ +#define VIA_VT1623 0x03 /* also VT1622A */ +#define VIA_VT1625 0x04 + +#define VIA_CH7011 0x10 #define VIA_TVNORMAL 0 #define VIA_TVOVER 1 @@ -147,4 +149,8 @@ void ViaDisablePrimaryFIFO(ScrnInfoPtr pScrn); I2CDevPtr ViaVT162xDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); void ViaVT162xInit(ScrnInfoPtr pScrn); +/* via_ch7xxx.c */ +I2CDevPtr ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address); +void ViaCH7xxxInit(ScrnInfoPtr pScrn); + #endif /* _VIA_BIOS_H_ */ diff --git a/src/via_ch7xxx.c b/src/via_ch7xxx.c new file mode 100644 index 0000000..ee4c36b --- /dev/null +++ b/src/via_ch7xxx.c @@ -0,0 +1,445 @@ +/* + * Copyright 2005 The Unichrome Project [unichrome.sf.net] + * + * 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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 "via_driver.h" +#include "via_ch7xxx.h" +#include "via_vgahw.h" +#include "via_id.h" + +/* + * + */ +I2CDevPtr +ViaCH7xxxDetect(ScrnInfoPtr pScrn, I2CBusPtr pBus, CARD8 Address) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + I2CDevPtr pDev = xf86CreateI2CDevRec(); + CARD8 buf; + + VIAFUNC(pScrn->scrnIndex); + + pDev->DevName = "CH7xxx"; + pDev->SlaveAddr = Address; + pDev->pI2CBus = pBus; + + if (!xf86I2CDevInit(pDev)) { + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + if (!xf86I2CReadByte(pDev, 0x4B, &buf)) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to read from %s Slave %d.\n", + pBus->BusName, Address); + xf86DestroyI2CDevRec(pDev, TRUE); + return NULL; + } + + switch (buf) { + case 0x17: + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected Chrontel CH7011 TV Encoder\n"); + pBIOSInfo->TVEncoder = VIA_CH7011; + pDev->DevName = "CH7011"; + break; + default: + pBIOSInfo->TVEncoder = VIA_NONETV; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Unknown TV Encoder found at %s %X (device id: 0x%02X).\n", + pBus->BusName, Address, buf); + xf86DestroyI2CDevRec(pDev,TRUE); + pDev = NULL; + break; + } + + return pDev; +} + +/* + * + */ +static void +CH7xxxPrintRegs(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 i, buf; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Printing registers for %s\n", + pBIOSInfo->TVI2CDev->DevName); + + for (i = 0; i < 0x4C; i++) { + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &buf); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s %02X: 0x%02X\n", + pBIOSInfo->TVI2CDev->DevName, i, buf); + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "End of %s registers.\n", + pBIOSInfo->TVI2CDev->DevName); +} + +/* + * + */ +static void +CH7011Save(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + int i; + + VIAFUNC(pScrn->scrnIndex); + + for (i = 0; i < 0x11; i++) + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); + + for (i = 0x1C; i < 0x22; i++) + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); + + i = 0x48; + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); + i = 0x49; + xf86I2CReadByte(pBIOSInfo->TVI2CDev, i, &(pBIOSInfo->TVRegs[i])); + /* pBIOSInfo->TVRegs[0x10] = 0x00; */ + + /* Fix common restoration issue: When !CIVEN then force CIVC1 = 0 */ + if ((pBIOSInfo->TVRegs[0x10] & 0x11) == 0x10) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Caught bad restoration " + "(CIVC).\n", __FUNCTION__); + pBIOSInfo->TVRegs[0x10] &= 0xEF; + } + +} + +/* + * + */ +static void +CH7011Restore(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 save; + int i; + + VIAFUNC(pScrn->scrnIndex); + + for (i = 0; i < 0x11; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); + + for (i = 0x1C; i < 0x22; i++) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, i, pBIOSInfo->TVRegs[i]); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x48, pBIOSInfo->TVRegs[0x48]); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, pBIOSInfo->TVRegs[0x49]); + + usleep(1); + + /* Fix common restoration issue: When !CIVEN then force CIVC1 = 0 */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x10, &save); + /* if ((save & 0x11) == 0x10) { */ + if (save != pBIOSInfo->TVRegs[0x10]) { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Caught bad restoration " + "(CIVC).\n", __FUNCTION__); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x10, save & 0xEF); + } +} + +/* + * + */ +static CARD8 +CH7xxxTVDACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 dacsave, save, sense; + + VIAFUNC(pScrn->scrnIndex); + + /* Enable all DACs */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x49, &dacsave); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20); + + /* Disable bypass mode: DACBP = 0 */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x21, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x21, save & 0xFE); + + /* SENSE = 1 */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x20, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x20, save | 0x01); + + pBIOSInfo->TVI2CDev->pI2CBus->I2CUDelay(pBIOSInfo->TVI2CDev->pI2CBus, 10); + + /* Restore SENSE */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x20, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x20, save & 0xFE); + + /* Read DAC0-3 */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x20, &sense); + + sense >>= 1; + sense &= 0x0F; + + ViaDebug(pScrn->scrnIndex, "%s: Sense: 0x%01X\n", __FUNCTION__, sense); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, dacsave); + + return sense; +} + +/* + * + */ +static Bool +CH7011DACSense(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 sense; + + VIAFUNC(pScrn->scrnIndex); + + sense = CH7xxxTVDACSense(pScrn); + + switch (sense) { + case 0x08: + pBIOSInfo->TVOutput = TVOUTPUT_COMPOSITE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s: Composite connected.\n", + pBIOSInfo->TVI2CDev->DevName); + return TRUE; + case 0x06: + pBIOSInfo->TVOutput = TVOUTPUT_SVIDEO; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s: S-Video connected.\n", + pBIOSInfo->TVI2CDev->DevName); + return TRUE; + case 0x0E: + pBIOSInfo->TVOutput = TVOUTPUT_SC; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s: Composite+S-Video connected.\n", + pBIOSInfo->TVI2CDev->DevName); + return TRUE; + case 0x00: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "%s: Nothing connected.\n", + pBIOSInfo->TVI2CDev->DevName); + return FALSE; + default: + pBIOSInfo->TVOutput = TVOUTPUT_NONE; + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "%s: Unknown cable combination: 0x0%2X.\n", + pBIOSInfo->TVI2CDev->DevName, sense); + return FALSE; + } +} + +/* + * + */ +static ModeStatus +CH7011TVModeValid(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + struct CH7011TableRec *Table = NULL; + char ID[12] = CH7011ID; + int i; + + VIAFUNC(pScrn->scrnIndex); + + if (mode->PrivSize == sizeof(struct CH7011TableRec)) + Table = (struct CH7011TableRec *) mode->Private; + + if (!Table || strncmp(ID, Table->ID, 12)) { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Not a mode defined by the TV Encoder.\n"); + return MODE_BAD; + } + + if (pBIOSInfo->TVType != Table->Standard) { + if (pBIOSInfo->TVType == TVTYPE_NTSC) + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is NTSC. This is a PAL mode.\n"); + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "TV standard is PAL. This is a NTSC mode.\n"); + return MODE_BAD; + } + + /* Look for matching clock. */ + for (i = 0; CH7011Clocks[i].Clock; i++) + if (CH7011Clocks[i].Clock == mode->Clock) + return MODE_OK; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: Unable to find matching dotclock.\n", + __FUNCTION__); + return MODE_BAD; +} + +static void +CH7011TVClock(I2CDevPtr TVI2CDev, int clock) +{ + int i; + + /* Look for matching clock. */ + for (i = 0; CH7011Clocks[i].Clock; i++) + if (CH7011Clocks[i].Clock == clock) + break; + + if (CH7011Clocks[i].Clock) { + xf86I2CWriteByte(TVI2CDev, 0x09, 0x80 | ((CH7011Clocks[i].PLLN >> 5) & 0x18) | + ((CH7011Clocks[i].PLLM >> 6) & 0x04) | + (CH7011Clocks[i].PLLCap ? 0x01 : 0x00)); + + xf86I2CWriteByte(TVI2CDev, 0x0A, CH7011Clocks[i].PLLM & 0xFF); + xf86I2CWriteByte(TVI2CDev, 0x0B, CH7011Clocks[i].PLLN & 0xFF); + } +} + +/* + * ModeValid should ensure that only modes with proper privates are passed here. + */ +static void +CH7011TVMode(ScrnInfoPtr pScrn, DisplayModePtr mode) +{ + VIAPtr pVia = VIAPTR(pScrn); + VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; + struct CH7011TableRec *Table = NULL; + CARD8 tmp; + int i; + + VIAFUNC(pScrn->scrnIndex); + + Table = (struct CH7011TableRec *) mode->Private; + + /* Disable TV avoid set mode garbage */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xD0); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x00, Table->Mode); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x01, 0x3F); + + /* low pass filter */ + if (Table->Standard == TVTYPE_NTSC) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0x7E); /* default */ + else + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x02, 0xE0); /* default */ + + /* Text Enhancement */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &tmp); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, tmp | 0x07); /* max */ + + /* Start Active Video */ + i = mode->CrtcHTotal - mode->CrtcHSyncEnd + 1; + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &tmp); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, (tmp & 0xDF) | ((i >> 3) & 0x20)); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x04, i & 0xFF); + + /* Horizontal Position */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &tmp); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, (tmp & 0xEF) | ((Table->HPosition >> 4) & 0x10)); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x05, Table->HPosition & 0xFF); + + /* Vertical Position */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x03, &tmp); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x03, (tmp & 0xF7) | ((Table->VPosition >> 5) & 0x08)); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x06, Table->VPosition & 0xFF); + + /* Black level */ + if (Table->Standard == TVTYPE_NTSC) + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x07, 0x83); /* default */ + else + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x07, 0x6E); /* default */ + + /* contrast */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x08, 0x03); /* default to 3 */ + + + CH7011TVClock(pBIOSInfo->TVI2CDev, mode->Clock); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0C, (Table->FSCI >> 24) & 0xFF); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0D, (Table->FSCI >> 16) & 0xFF); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0E, (Table->FSCI >> 8) & 0xFF); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x0F, Table->FSCI & 0xFF); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x10, 0x00); + + /* stop dark band in lower half (undocumented register) */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x15, &tmp); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x15, tmp & 0xF8); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1C, 0x48); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1D, 0x40); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, 0xF2); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1F, 0x80); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x20, 0x40); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x21, 0x00); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x22, 0x00); + + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x48, 0x10); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x48, 0x18); + + /* Turn TV CH7011 DAC On */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20); +} + +/* + * + */ +static void +CH7xxxTVPower(ScrnInfoPtr pScrn, Bool On) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + CARD8 save; + + VIAFUNC(pScrn->scrnIndex); + + if (On) { + /* Plainly enables all DACs - should be more specific. */ + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x20); + + /* POUTE */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x1E, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, save | 0x02); + } else { + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x49, 0x3E); + + /* !POUTE */ + xf86I2CReadByte(pBIOSInfo->TVI2CDev, 0x1E, &save); + xf86I2CWriteByte(pBIOSInfo->TVI2CDev, 0x1E, save & ~0x02); + } +} + +/* + * + */ +void +ViaCH7xxxInit(ScrnInfoPtr pScrn) +{ + VIABIOSInfoPtr pBIOSInfo = VIAPTR(pScrn)->pBIOSInfo; + + VIAFUNC(pScrn->scrnIndex); + + switch (pBIOSInfo->TVEncoder) { + case VIA_CH7011: + pBIOSInfo->TVSave = CH7011Save; + pBIOSInfo->TVRestore = CH7011Restore; + pBIOSInfo->TVDACSense = CH7011DACSense; + pBIOSInfo->TVModeValid = CH7011TVModeValid; + pBIOSInfo->TVMode = CH7011TVMode; + pBIOSInfo->TVPower = CH7xxxTVPower; + pBIOSInfo->TVModes = CH7011TVModes; + pBIOSInfo->TVPrintRegs = CH7xxxPrintRegs; + break; + default: + break; + } +} diff --git a/src/via_ch7xxx.h b/src/via_ch7xxx.h new file mode 100644 index 0000000..bd7fe4c --- /dev/null +++ b/src/via_ch7xxx.h @@ -0,0 +1,149 @@ +/* + * Copyright 2005 The Unichrome Project [unichrome.sf.net] + * + * 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 + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef _VIA_CH7XXX_H_ +#define _VIA_CH7XXX_H_ 1 + +/* + * All the info here is nicely documented in Chrontel datasheets. + * Chrontel makes these freely available. Don't you just love 'em? + * + * We currently only implement PAL and NTSC. We don't care about + * NTSC (dotcrawl reduction), PAL-M or PAL-N. + */ + +static struct CH7011ClockRec { + int Clock; + Bool PLLCap; + CARD16 PLLM; + CARD16 PLLN; +} CH7011Clocks[] = { + { 13500, TRUE, 33, 31 }, + { 20140, FALSE, 89, 126 }, + { 21000, TRUE, 13, 20 }, + { 21147, FALSE, 63, 94 }, + { 23790, FALSE, 63, 106 }, + { 24671, FALSE, 63, 110 }, + { 25000, FALSE, 61, 108 }, + { 26182, TRUE, 33, 62 }, + { 26250, TRUE, 4, 9 }, + { 27563, TRUE, 38, 75 }, + { 27755, FALSE, 63, 124 }, + { 28125, TRUE, 26, 53 }, + { 28196, FALSE, 63, 126 }, + { 29455, TRUE, 33, 70 }, + { 29500, FALSE, 313, 647 }, + { 30210, FALSE, 89, 190 }, + { 31500, TRUE, 3, 9 }, + { 31720, FALSE, 63, 142 }, + { 33750, TRUE, 12, 31 }, + { 33986, FALSE, 89, 214 }, + { 36000, TRUE, 33, 86 }, + { 39375, TRUE, 2, 9 }, + { 42000, TRUE, 13, 42 }, + { 43636, TRUE, 19, 62 }, + { 47832, FALSE, 89, 302 }, + { 52364, TRUE, 33, 126 }, + { 58406, FALSE, 137, 565 }, + { 61250, TRUE, 16, 75 }, + { 65706, FALSE, 71, 333 }, + { 70000, TRUE, 7, 42 }, + { 73510, FALSE, 177, 917 }, + { 78750, TRUE, 2, 20 }, + { 0, FALSE, 0, 0 }, +}; + +#define CH7011ID { 'C', 'H', '7', '0', '1', '1', 0, 0, 0, 0, 0, 0 } + +struct CH7011TableRec { + char ID[12]; /* "CH7xxx" */ + int Standard; + CARD8 Mode; + CARD32 FSCI; + CARD16 HPosition; /* touch me. */ + CARD16 VPosition; /* touch me. */ +}; + +static struct CH7011TableRec CH7011TVTable[40] = { + { CH7011ID, TVTYPE_PAL, 0x00, 806021060, 0x028, 0x0FA }, /* 00 */ + { CH7011ID, TVTYPE_PAL, 0x01, 644816848, 0x028, 0x138 }, /* 01 */ + { CH7011ID, TVTYPE_NTSC, 0x08, 763363328, 0x028, 0x0D2 }, /* 02 */ + { CH7011ID, TVTYPE_NTSC, 0x09, 623153737, 0x028, 0x106 }, /* 03 */ + { CH7011ID, TVTYPE_PAL, 0x20, 601829058, 0x028, 0x0FA }, /* 04 */ + { CH7011ID, TVTYPE_PAL, 0x21, 470178951, 0x028, 0x138 }, /* 05 */ + { CH7011ID, TVTYPE_NTSC, 0x28, 574429782, 0x028, 0x0D2 }, /* 06 */ + { CH7011ID, TVTYPE_NTSC, 0x29, 463962517, 0x028, 0x106 }, /* 07 */ + { CH7011ID, TVTYPE_PAL, 0x40, 677057690, 0x028, 0x0FA }, /* 08 */ + { CH7011ID, TVTYPE_PAL, 0x41, 537347373, 0x028, 0x138 }, /* 09 */ + { CH7011ID, TVTYPE_NTSC, 0x48, 646233505, 0x028, 0x0D2 }, /* 10 */ + { CH7011ID, TVTYPE_NTSC, 0x49, 521957831, 0x028, 0x106 }, /* 11 */ + { CH7011ID, TVTYPE_NTSC, 0x4A, 452363454, 0x028, 0x12C }, /* 12 */ + { CH7011ID, TVTYPE_PAL, 0x60, 806021060, 0x01B, 0x12D }, /* 13 */ + { CH7011ID, TVTYPE_PAL, 0x61, 644816848, 0x035, 0x133 }, /* 14 */ + { CH7011ID, TVTYPE_PAL, 0x62, 537347373, 0x028, 0x177 }, /* 15 */ + { CH7011ID, TVTYPE_NTSC, 0x69, 623153737, 0x019, 0x100 }, /* 16 */ + { CH7011ID, TVTYPE_NTSC, 0x6A, 545259520, 0x02E, 0x104 }, /* 17 */ + { CH7011ID, TVTYPE_NTSC, 0x6B, 508908885, 0x028, 0x13B }, /* 18 */ + { CH7011ID, TVTYPE_NTSC, 0x89, 553914433, 0x028, 0x106 }, /* 19 */ + { CH7011ID, TVTYPE_NTSC, 0x8A, 484675129, 0x028, 0x12C }, /* 20 */ + { CH7011ID, TVTYPE_NTSC, 0x8B, 452363454, 0x028, 0x13B }, /* 21 */ + { CH7011ID, TVTYPE_PAL, 0xA1, 690875194, 0x028, 0x138 }, /* 22 */ + { CH7011ID, TVTYPE_PAL, 0xA2, 564214742, 0x028, 0x177 }, /* 23 */ + { CH7011ID, TVTYPE_PAL, 0xA3, 483612636, 0x028, 0x1B5 }, /* 24 */ + { CH7011ID, TVTYPE_PAL, 0xC1, 645499916, 0x01D, 0x136 }, /* 25 */ + { CH7011ID, TVTYPE_PAL, 0xC3, 528951320, 0x03F, 0x138 }, /* 26 */ + { CH7011ID, TVTYPE_PAL, 0xC4, 453386846, 0x028, 0x1B5 }, /* 27 */ + { CH7011ID, TVTYPE_NTSC, 0xCE, 469762048, 0x02E, 0x110 }, /* 28 */ + { CH7011ID, TVTYPE_NTSC, 0xCF, 428554851, 0x03C, 0x115 }, /* 29 */ + { CH7011ID, TVTYPE_NTSC, 0xCD, 391468373, 0x028, 0x1A4 }, /* 30 */ + { CH7011ID, TVTYPE_PAL, 0xE4, 621787675, 0x028, 0x137 }, /* 31 */ + { CH7011ID, TVTYPE_PAL, 0xE5, 544064215, 0x03E, 0x14A }, /* 32 */ + { CH7011ID, TVTYPE_PAL, 0xE6, 483612636, 0x028, 0x1FF }, /* 33 */ + { CH7011ID, TVTYPE_NTSC, 0xED, 526457468, 0x020, 0 }, /* 34 */ + { CH7011ID, TVTYPE_NTSC, 0xEE, 467962193, 0x032, 0x009 }, /* 35 */ + { CH7011ID, TVTYPE_NTSC, 0xEF, 418281276, 0x028, 0x1FF }, /* 36 */ + { CH7011ID, TVTYPE_PAL, 0xA0, 705268427, 0x028, 0x138 }, /* 37 */ + { CH7011ID, TVTYPE_NTSC, 0x88, 569408543, 0x028, 0x106 }, /* 38 */ +}; + +#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DEFAULT +#define MODESUFFIX(bleh) 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE, \ +sizeof(struct CH7011TableRec), (void *)&CH7011TVTable[(bleh)],0,0.0,0.0 + +static DisplayModeRec CH7011TVModes[] = { + { MODEPREFIX("640x480Over"), 21000, 640, 664, 792, 840, 0, 480, 485, 496, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(13) }, /* 13 */ + { MODEPREFIX("640x480"), 26250, 640, 664, 792, 840, 0, 480, 529, 544, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(14) }, /* 14 */ + { MODEPREFIX("640x480Over"), 24671, 640, 656, 752, 784, 0, 480, 494, 496, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(16) }, /* 16 */ + { MODEPREFIX("640x480"), 28196, 640, 656, 752, 784, 0, 480, 520, 528, 600, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(17) }, /* 17 */ + { MODEPREFIX("800x600Over"), 29500, 800, 824, 896, 944, 0, 600, 602, 608, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX(25) }, /* 25 */ + { MODEPREFIX("800x600"), 36000, 800, 824, 904, 960, 0, 600, 638, 640, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX(26) }, /* 26 */ + { MODEPREFIX("800x600Over"), 43636, 800, 840, 960, 1040, 0, 600, 602, 608, 700, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX(28) }, /* 28 */ + { MODEPREFIX("800x600"), 47832, 800, 840, 976, 1064, 0, 600, 604, 608, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX(29) }, /* 29 */ + { MODEPREFIX("1024x768Over"), 61250, 1024, 1056, 1208, 1400, 0, 768, 775, 784, 875, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(31) }, /* 31 */ + { MODEPREFIX("1024x768"), 70000, 1024, 1048, 1208, 1400, 0, 768, 785, 800, 1000, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(32) }, /* 32 */ + { MODEPREFIX("1024x768Over"), 58406, 1024, 1032, 1088, 1160, 0, 768, 772, 784, 840, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(34) }, /* 34 */ + { MODEPREFIX("1024x768"), 65706, 1024, 1032, 1088, 1160, 0, 768, 780, 784, 945, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX(35) }, /* 35 */ + { MODEPREFIX(NULL), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE, 0, NULL, 0,0.0,0.0}, +}; + +#endif /* _VIA_CH7XXX_H_ */ diff --git a/src/via_mode.c b/src/via_mode.c index fe93d26..44b37fe 100644 --- a/src/via_mode.c +++ b/src/via_mode.c @@ -69,10 +69,18 @@ ViaTVDetect(ScrnInfoPtr pScrn) pBIOSInfo->TVModes = NULL; pBIOSInfo->TVPrintRegs = NULL; - if (pVia->pI2CBus2 && xf86I2CProbeAddress(pVia->pI2CBus2, 0x40)) - pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus2, 0x40); - else if (pVia->pI2CBus3 && xf86I2CProbeAddress(pVia->pI2CBus3, 0x40)) - pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus3, 0x40); + if (pVia->pI2CBus2) { + if (xf86I2CProbeAddress(pVia->pI2CBus2, 0x40)) + pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus2, 0x40); + else if (xf86I2CProbeAddress(pVia->pI2CBus2, 0xEC)) + pBIOSInfo->TVI2CDev = ViaCH7xxxDetect(pScrn, pVia->pI2CBus2, 0xEC); + } + if (!pBIOSInfo->TVI2CDev && pVia->pI2CBus3) { + if (xf86I2CProbeAddress(pVia->pI2CBus3, 0x40)) + pBIOSInfo->TVI2CDev = ViaVT162xDetect(pScrn, pVia->pI2CBus3, 0x40); + else if (xf86I2CProbeAddress(pVia->pI2CBus3, 0xEC)) + ViaDebug(pScrn->scrnIndex, "We have chrontel on 3!\n"); + } if (pBIOSInfo->TVI2CDev) return TRUE; @@ -95,6 +103,9 @@ ViaTVInit(ScrnInfoPtr pScrn) case VIA_VT1623: ViaVT162xInit(pScrn); break; + case VIA_CH7011: + ViaCH7xxxInit(pScrn); + break; default: return FALSE; break; |