summaryrefslogtreecommitdiff
path: root/src/g80_output.c
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2007-03-27 13:33:11 -0700
committerAaron Plattner <aplattner@nvidia.com>2007-03-27 14:49:55 -0700
commit4b8ed8497a9ab6ef1316bfcce9f31d96dd4b3540 (patch)
tree21ed86efe443622852e48d50bd03aebb32e96548 /src/g80_output.c
parentad4abba20b8a6db7b52898bc7159809539cbed43 (diff)
G80: Create output partners.
Each pair of outputs shares an I2C rec. This will be used in a future change for the detect and get_modes routines.
Diffstat (limited to 'src/g80_output.c')
-rw-r--r--src/g80_output.c56
1 files changed, 43 insertions, 13 deletions
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;
}
-