From 9d4f66b2af6b5bd23e56fa37293d5c1b95a6c382 Mon Sep 17 00:00:00 2001 From: Kevin Brace Date: Wed, 20 Jan 2016 18:04:50 -0600 Subject: [PATCH 6/9] Using I2C bus 2 to also detect a VGA monitor Previously, it was assumed that only I2C bus 1 is used to detect a VGA monitor. I2C bus 2 is typically used to detect a DVI monitor via a DVI connector. For devices with a DVI-I connector, VGA signals come out of the connector. What this means is that I2C bus 2 also has to be used to detect a VGA monitor, in addition to I2C bus 1. --- src/via_outputs.c | 128 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 85 insertions(+), 43 deletions(-) diff --git a/src/via_outputs.c b/src/via_outputs.c index 968262d..b5e76e6 100644 --- a/src/via_outputs.c +++ b/src/via_outputs.c @@ -800,50 +800,76 @@ via_analog_detect(xf86OutputPtr output) VIAPtr pVia = VIAPTR(pScrn); xf86MonPtr mon; + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Entered via_analog_detect.\n")); + + /* Probe I2C Bus 1 to see if a VGA monitor is connected. */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Probing for a VGA monitor on I2C Bus 1.\n")); mon = xf86OutputGetEDID(output, pVia->pI2CBus1); if (mon) { - xf86OutputSetEDID(output, mon); DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "DDC pI2CBus1 detected a CRT\n")); + "Detected a VGA monitor on I2C Bus 1.\n")); + xf86OutputSetEDID(output, mon); status = XF86OutputStatusConnected; } else { - vgaHWPtr hwp = VGAHWPTR(pScrn); - CARD8 SR01 = hwp->readSeq(hwp, 0x01); - CARD8 SR40 = hwp->readSeq(hwp, 0x40); - CARD8 CR36 = hwp->readCrtc(hwp, 0x36); - - DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "Test for CRT with VSYNC\n")); - /* We have to power on the display to detect it */ - ViaSeqMask(hwp, 0x01, 0x00, 0x20); - ViaCrtcMask(hwp, 0x36, 0x00, 0xF0); - /* Wait for vblank */ - usleep(16); - - /* Detect the load on pins */ - ViaSeqMask(hwp, 0x40, 0x80, 0x80); - - if ((VIA_CX700 == pVia->Chipset) || - (VIA_VX800 == pVia->Chipset) || - (VIA_VX855 == pVia->Chipset) || - (VIA_VX900 == pVia->Chipset)) - ViaSeqMask(hwp, 0x40, 0x00, 0x80); - - if (ViaVgahwIn(hwp, 0x3C2) & 0x20) + /* Probe I2C Bus 2 to see if a VGA monitor is connected. */ + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Probing for a VGA monitor on I2C Bus 2.\n")); + mon = xf86OutputGetEDID(output, pVia->pI2CBus2); + if (mon) { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected a VGA monitor on I2C Bus 2.\n")); + xf86OutputSetEDID(output, mon); status = XF86OutputStatusConnected; - - if ((VIA_CX700 == pVia->Chipset) || - (VIA_VX800 == pVia->Chipset) || - (VIA_VX855 == pVia->Chipset) || - (VIA_VX900 == pVia->Chipset)) - ViaSeqMask(hwp, 0x40, 0x00, 0x80); - - /* Restore previous state */ - hwp->writeSeq(hwp, 0x40, SR40); - hwp->writeSeq(hwp, 0x01, SR01); - hwp->writeCrtc(hwp, 0x36, CR36); + } else { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Did not detect a VGA monitor using " + "I2C bus.\n")); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Now perform manual detection of a VGA " + "monitor.\n")); + + vgaHWPtr hwp = VGAHWPTR(pScrn); + CARD8 SR01 = hwp->readSeq(hwp, 0x01); + CARD8 SR40 = hwp->readSeq(hwp, 0x40); + CARD8 CR36 = hwp->readCrtc(hwp, 0x36); + + /* We have to power on the display to detect it */ + ViaSeqMask(hwp, 0x01, 0x00, 0x20); + ViaCrtcMask(hwp, 0x36, 0x00, 0xF0); + + /* Wait for vblank */ + usleep(16); + + /* Detect the load on pins */ + ViaSeqMask(hwp, 0x40, 0x80, 0x80); + + if ((VIA_CX700 == pVia->Chipset) || + (VIA_VX800 == pVia->Chipset) || + (VIA_VX855 == pVia->Chipset) || + (VIA_VX900 == pVia->Chipset)) + ViaSeqMask(hwp, 0x40, 0x00, 0x80); + + if (ViaVgahwIn(hwp, 0x3C2) & 0x20) + status = XF86OutputStatusConnected; + + if ((VIA_CX700 == pVia->Chipset) || + (VIA_VX800 == pVia->Chipset) || + (VIA_VX855 == pVia->Chipset) || + (VIA_VX900 == pVia->Chipset)) + ViaSeqMask(hwp, 0x40, 0x00, 0x80); + + /* Restore previous state */ + hwp->writeSeq(hwp, 0x40, SR40); + hwp->writeSeq(hwp, 0x01, SR01); + hwp->writeCrtc(hwp, 0x36, CR36); + } } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Exiting via_analog_detect.\n")); return status; } @@ -871,22 +897,38 @@ static const xf86OutputFuncsRec via_analog_funcs = { .destroy = via_analog_destroy, }; -void +static Bool via_analog_init(ScrnInfoPtr pScrn) { VIAPtr pVia = VIAPTR(pScrn); VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo; xf86OutputPtr output = NULL; - if (pVia->pI2CBus1) { + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Entered via_analog_init.\n")); + + if ((pVia->pI2CBus1) || (pVia->pI2CBus2)) { output = xf86OutputCreate(pScrn, &via_analog_funcs, "VGA-1"); - output->possible_crtcs = 0x3; - output->possible_clones = 0; - output->interlaceAllowed = TRUE; - output->doubleScanAllowed = FALSE; - pBIOSInfo->analog = output; + if (output) { + output->possible_crtcs = 0x3; + output->possible_clones = 0; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = FALSE; + pBIOSInfo->analog = output; + + } else { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to register VGA-1.\n"); + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Exiting via_analog_init.\n")); + return FALSE; + } } + + DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Exiting via_analog_init.\n")); + return TRUE; } static void -- 1.7.9.5