summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/g80_dac.c5
-rw-r--r--src/g80_output.c56
-rw-r--r--src/g80_output.h6
-rw-r--r--src/g80_sor.c5
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;
}