From 1f2590b0579ed225d7852d077910f44424e826c8 Mon Sep 17 00:00:00 2001 From: Kevin Brace Date: Sun, 21 Feb 2016 13:13:31 -0800 Subject: [PATCH 1/3] Using I2C bus 2 to 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. However, for devices with a DVI-I connector, VGA signals come out of the connector as well. What this means is that I2C bus 2 also has to be used to detect a VGA monitor, in addition to I2C bus 1. Furthermore, EDID obtained from the monitor via I2C bus will be used to determine whether or not it is an analog type (i.e., VGA monitor). Reported-by: Christopher Tested-by: Justin Chevrier Signed-off-by: Kevin Brace --- src/via_outputs.c | 97 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/src/via_outputs.c b/src/via_outputs.c index 8034911..ada1666 100644 --- a/src/via_outputs.c +++ b/src/via_outputs.c @@ -804,50 +804,73 @@ via_analog_detect(xf86OutputPtr output) VIAPtr pVia = VIAPTR(pScrn); xf86MonPtr mon; + /* Probe I2C Bus 1 to see if a VGA monitor is connected. */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Probing for a VGA monitor on I2C Bus 1.\n"); mon = xf86OutputGetEDID(output, pVia->pI2CBus1); - if (mon) { + if (mon && (!mon->features.input_type)) { xf86OutputSetEDID(output, mon); - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "I2C Bus 1 detected a VGA monitor.\n"); status = XF86OutputStatusConnected; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected a VGA monitor on I2C Bus 1.\n"); } 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. */ + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Probing for a VGA monitor on I2C Bus 2.\n"); + mon = xf86OutputGetEDID(output, pVia->pI2CBus2); + if (mon && (!mon->features.input_type)) { + xf86OutputSetEDID(output, mon); status = XF86OutputStatusConnected; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected a VGA monitor on I2C Bus 2.\n"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Did not detect a VGA monitor on I2C Bus 1 " + "or I2C Bus 2.\n"); + 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; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "Detected a VGA monitor using manual " + "detection method.\n"); + } - if ((VIA_CX700 == pVia->Chipset) || - (VIA_VX800 == pVia->Chipset) || - (VIA_VX855 == pVia->Chipset) || - (VIA_VX900 == pVia->Chipset)) - ViaSeqMask(hwp, 0x40, 0x00, 0x80); + 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); + /* Restore previous state */ + hwp->writeSeq(hwp, 0x40, SR40); + hwp->writeSeq(hwp, 0x01, SR01); + hwp->writeCrtc(hwp, 0x36, CR36); + } } + return status; } @@ -885,7 +908,7 @@ via_analog_init(ScrnInfoPtr pScrn) DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Entered via_analog_init.\n")); - if (pVia->pI2CBus1) { + if ((pVia->pI2CBus1) && (pVia->pI2CBus2)) { output = xf86OutputCreate(pScrn, &via_analog_funcs, "VGA-1"); output->possible_crtcs = 0x3; -- 1.7.9.5