diff options
-rw-r--r-- | src/g80_dac.c | 5 | ||||
-rw-r--r-- | src/g80_output.c | 56 | ||||
-rw-r--r-- | src/g80_output.h | 6 | ||||
-rw-r--r-- | src/g80_sor.c | 5 |
4 files changed, 48 insertions, 24 deletions
diff --git a/src/g80_dac.c b/src/g80_dac.c index 991e3be..bb86748 100644 --- a/src/g80_dac.c +++ b/src/g80_dac.c @@ -130,7 +130,7 @@ static const xf86OutputFuncsRec G80DacOutputFuncs = { }; xf86OutputPtr -G80CreateDac(ScrnInfoPtr pScrn, ORNum or, int i2cPort) +G80CreateDac(ScrnInfoPtr pScrn, ORNum or) { G80OutputPrivPtr pPriv = xnfcalloc(sizeof(*pPriv), 1); xf86OutputPtr output; @@ -149,8 +149,5 @@ G80CreateDac(ScrnInfoPtr pScrn, ORNum or, int i2cPort) output->interlaceAllowed = TRUE; output->doubleScanAllowed = TRUE; - /* Create an I2C object */ - G80I2CInit(output, i2cPort); - return output; } diff --git a/src/g80_output.c b/src/g80_output.c index b56bf00..d847e2e 100644 --- a/src/g80_output.c +++ b/src/g80_output.c @@ -127,18 +127,17 @@ static void G80_I2CGetBits(I2CBusPtr b, int *clock, int *data) *data = !!(val & 2); } -Bool -G80I2CInit(xf86OutputPtr output, const int port) +static I2CBusPtr +G80I2CInit(ScrnInfoPtr pScrn, const char *name, const int port) { - G80OutputPrivPtr pPriv = output->driver_private; I2CBusPtr i2c; /* Allocate the I2C bus structure */ i2c = xf86CreateI2CBusRec(); - if(!i2c) return FALSE; + if(!i2c) return NULL; - i2c->BusName = output->name; - i2c->scrnIndex = output->scrn->scrnIndex; + i2c->BusName = strdup(name); + i2c->scrnIndex = pScrn->scrnIndex; i2c->I2CPutBits = G80_I2CPutBits; i2c->I2CGetBits = G80_I2CGetBits; i2c->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ @@ -149,11 +148,10 @@ G80I2CInit(xf86OutputPtr output, const int port) i2c->DriverPrivate.val = port; if(xf86I2CBusInit(i2c)) { - pPriv->i2c = i2c; - return TRUE; + return i2c; } else { xfree(i2c); - return FALSE; + return NULL; } } @@ -227,7 +225,10 @@ G80OutputDestroy(xf86OutputPtr output) { G80OutputPrivPtr pPriv = output->driver_private; - xf86DestroyI2CBusRec(pPriv->i2c, TRUE, TRUE); + if(pPriv->partner) + ((G80OutputPrivPtr)pPriv->partner->driver_private)->partner = NULL; + else + xf86DestroyI2CBusRec(pPriv->i2c, TRUE, TRUE); pPriv->i2c = NULL; } @@ -243,10 +244,40 @@ G80CreateOutputs(ScrnInfoPtr pScrn) /* For each DDC port, create an output for the attached ORs */ for(i = 0; i < 4; i++) { + xf86OutputPtr dac = NULL, sor = NULL; + I2CBusPtr i2c; + char i2cName[16]; + + if(pNv->i2cMap[i].dac == -1 && pNv->i2cMap[i].sor == -1) + /* No outputs on this port */ + continue; + + snprintf(i2cName, sizeof(i2cName), "I2C%i", i); + i2c = G80I2CInit(pScrn, i2cName, i); + if(!i2c) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize I2C for port %i.\n", + i); + continue; + } + if(pNv->i2cMap[i].dac != -1) - G80CreateDac(pScrn, pNv->i2cMap[i].dac, i); + dac = G80CreateDac(pScrn, pNv->i2cMap[i].dac); if(pNv->i2cMap[i].sor != -1) - G80CreateSor(pScrn, pNv->i2cMap[i].sor, i); + sor = G80CreateSor(pScrn, pNv->i2cMap[i].sor); + + if(dac) { + G80OutputPrivPtr pPriv = dac->driver_private; + + pPriv->partner = sor; + pPriv->i2c = i2c; + } + if(sor) { + G80OutputPrivPtr pPriv = sor->driver_private; + + pPriv->partner = dac; + pPriv->i2c = i2c; + } } /* For each output, set the crtc and clone masks */ @@ -260,4 +291,3 @@ G80CreateOutputs(ScrnInfoPtr pScrn) return TRUE; } - diff --git a/src/g80_output.h b/src/g80_output.h index efc9a16..819df15 100644 --- a/src/g80_output.h +++ b/src/g80_output.h @@ -2,12 +2,12 @@ typedef struct G80OutputPrivRec { ORType type; ORNum or; + xf86OutputPtr partner; I2CBusPtr i2c; void (*set_pclk)(xf86OutputPtr, int pclk); } G80OutputPrivRec, *G80OutputPrivPtr; -Bool G80I2CInit(xf86OutputPtr, const int port); void G80OutputSetPClk(xf86OutputPtr, int pclk); int G80OutputModeValid(xf86OutputPtr, DisplayModePtr); Bool G80OutputModeFixup(xf86OutputPtr, DisplayModePtr mode, DisplayModePtr adjusted_mode); @@ -18,7 +18,7 @@ void G80OutputDestroy(xf86OutputPtr); Bool G80CreateOutputs(ScrnInfoPtr); /* g80_dac.c */ -xf86OutputPtr G80CreateDac(ScrnInfoPtr, ORNum, int i2cPort); +xf86OutputPtr G80CreateDac(ScrnInfoPtr, ORNum); /* g80_sor.c */ -xf86OutputPtr G80CreateSor(ScrnInfoPtr, ORNum, int i2cPort); +xf86OutputPtr G80CreateSor(ScrnInfoPtr, ORNum); diff --git a/src/g80_sor.c b/src/g80_sor.c index 7d377a8..55a643f 100644 --- a/src/g80_sor.c +++ b/src/g80_sor.c @@ -114,7 +114,7 @@ static const xf86OutputFuncsRec G80SorOutputFuncs = { }; xf86OutputPtr -G80CreateSor(ScrnInfoPtr pScrn, ORNum or, int i2cPort) +G80CreateSor(ScrnInfoPtr pScrn, ORNum or) { G80OutputPrivPtr pPriv = xnfcalloc(sizeof(*pPriv), 1); xf86OutputPtr output; @@ -133,8 +133,5 @@ G80CreateSor(ScrnInfoPtr pScrn, ORNum or, int i2cPort) output->interlaceAllowed = TRUE; output->doubleScanAllowed = TRUE; - /* Create an I2C object */ - G80I2CInit(output, i2cPort); - return output; } |