xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Sat Feb 2 21:10:07 PST 2008


 src/legacy_output.c   |    3 
 src/radeon.h          |    3 
 src/radeon_atombios.c |   66 +++++++-------
 src/radeon_bios.c     |   70 +++++++++------
 src/radeon_output.c   |  221 +++++++++++++++++++++++---------------------------
 src/radeon_probe.h    |   22 ++--
 6 files changed, 198 insertions(+), 187 deletions(-)

New commits:
commit f65e8dfac23adfa199026765fe3a1ea08cf4da67
Author: Alex Deucher <alex at cube.(none)>
Date:   Sun Feb 3 00:09:59 2008 -0500

    RADEON: rework i2c handling
    
    Split out clk, data, and lock regs and masks.  some cards use different
    regs and masks for each.  For cards with ATOMBIOS, use the i2c bios
    table to grab the i2c data.

diff --git a/src/legacy_output.c b/src/legacy_output.c
index 8ae21b9..7ade772 100644
--- a/src/legacy_output.c
+++ b/src/legacy_output.c
@@ -284,7 +284,8 @@ RADEONRestoreDVOChip(ScrnInfoPtr pScrn, xf86OutputPtr output)
     if (!radeon_output->DVOChip)
 	return;
 
-    OUTREG(radeon_output->dvo_i2c_reg, INREG(radeon_output->dvo_i2c_reg) &
+    OUTREG(radeon_output->dvo_i2c.mask_clk_reg,
+	   INREG(radeon_output->dvo_i2c.mask_clk_reg) &
 	   (CARD32)~(RADEON_GPIO_A_0 | RADEON_GPIO_A_1));
 
     if (!RADEONInitExtTMDSInfoFromBIOS(output)) {
diff --git a/src/radeon.h b/src/radeon.h
index d538196..ec952b5 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -870,6 +870,9 @@ RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output);
 extern Bool
 RADEONInitExtTMDSInfoFromBIOS (xf86OutputPtr output);
 
+extern RADEONI2CBusRec
+legacy_setup_i2c_bus(int ddc_line);
+
 extern void
 radeon_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y);
 extern void
diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c
index b956b9a..e8f9e91 100644
--- a/src/radeon_atombios.c
+++ b/src/radeon_atombios.c
@@ -1401,10 +1401,10 @@ const int object_connector_convert[] =
       CONNECTOR_NONE,
       CONNECTOR_NONE,
     };
-     
+
 static void
 rhdAtomParseI2CRecord(atomBiosHandlePtr handle,
-			ATOM_I2C_RECORD *Record, CARD32 *ddc_line)
+			ATOM_I2C_RECORD *Record, int *line)
 {
     ErrorF(" %s:  I2C Record: %s[%x] EngineID: %x I2CAddr: %x\n",
 	     __func__,
@@ -1414,53 +1414,52 @@ rhdAtomParseI2CRecord(atomBiosHandlePtr handle,
 	     Record->ucI2CAddr);
 
     if (!*(unsigned char *)&(Record->sucI2cId))
-	*ddc_line = 0;
+	*line = 0;
     else {
 
 	if (Record->ucI2CAddr != 0)
 	    return;
-
-	if (Record->sucI2cId.bfHW_Capable) {
-	    switch(Record->sucI2cId.bfI2C_LineMux) {
-	    case 0: *ddc_line = 0x7e40; break;
-	    case 1: *ddc_line = 0x7e50; break;
-	    case 2: *ddc_line = 0x7e30; break;
-	    default: break;
-	    }
-	    return;
-	
-	} else {
-	    /* add GPIO pin parsing */
-	}
+	*line = Record->sucI2cId.bfI2C_LineMux;
+	return;
     }
 }
 
-static CARD32
+static RADEONI2CBusRec
 RADEONLookupGPIOLineForDDC(ScrnInfoPtr pScrn, CARD8 id)
 {
     RADEONInfoPtr info = RADEONPTR (pScrn);
     atomDataTablesPtr atomDataPtr;
     ATOM_GPIO_I2C_ASSIGMENT gpio;
-    CARD32 ret = 0;
+    RADEONI2CBusRec i2c;
     CARD8 crev, frev;
 
+    i2c.valid = FALSE;
+
     atomDataPtr = info->atomBIOS->atomDataPtr;
 
     if (!rhdAtomGetTableRevisionAndSize(
 	    &(atomDataPtr->GPIO_I2C_Info->sHeader),
 	    &crev,&frev,NULL)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "No GPIO Info Table found!\n");
-	return ret;
+	return i2c;
     }
 
-    /* note clk and data regs can be different!
-     * gpio.usClkMaskRegisterIndex and gpio.usDataMaskRegisterIndex
-     */
-
     gpio = atomDataPtr->GPIO_I2C_Info->asGPIO_Info[id];
-    ret = gpio.usClkMaskRegisterIndex * 4;
-
-    return ret;
+    i2c.mask_clk_reg = gpio.usClkMaskRegisterIndex * 4;
+    i2c.mask_data_reg = gpio.usDataMaskRegisterIndex * 4;
+    i2c.put_clk_reg = gpio.usClkEnRegisterIndex * 4;
+    i2c.put_data_reg = gpio.usDataEnRegisterIndex * 4;
+    i2c.get_clk_reg = gpio.usClkY_RegisterIndex * 4;
+    i2c.get_data_reg = gpio.usDataY_RegisterIndex * 4;
+    i2c.mask_clk_mask = (1 << gpio.ucClkMaskShift);
+    i2c.mask_data_mask = (1 << gpio.ucDataMaskShift);
+    i2c.put_clk_mask = (1 << gpio.ucClkEnShift);
+    i2c.put_data_mask = (1 << gpio.ucDataEnShift);
+    i2c.get_clk_mask = (1 << gpio.ucClkY_Shift);
+    i2c.get_data_mask = (1 <<  gpio.ucDataY_Shift);
+    i2c.valid = TRUE;
+
+    return i2c;
 }
 
 Bool
@@ -1471,7 +1470,7 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
     unsigned short size;
     atomDataTablesPtr atomDataPtr;
     ATOM_CONNECTOR_OBJECT_TABLE *con_obj;
-    int i, j;
+    int i, j, line = 0;
 
     atomDataPtr = info->atomBIOS->atomDataPtr;
     if (!rhdAtomGetTableRevisionAndSize((ATOM_COMMON_TABLE_HEADER *)(atomDataPtr->Object_Header), &crev, &frev, &size))
@@ -1559,7 +1558,8 @@ RADEONGetATOMConnectorInfoFromBIOSObject (ScrnInfoPtr pScrn)
 		case ATOM_I2C_RECORD_TYPE:
 		    rhdAtomParseI2CRecord(info->atomBIOS, 
 					  (ATOM_I2C_RECORD *)Record,
-					  &info->BiosConnector[i].ddc_line);
+					  &line);
+		    info->BiosConnector[i].ddc_i2c = RADEONLookupGPIOLineForDDC(pScrn, line);
 		    break;
 		case ATOM_HPD_INT_RECORD_TYPE:
 		    break;
@@ -1720,11 +1720,11 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
 	/* don't assign a gpio for tv */
 	if ((i == ATOM_DEVICE_TV1_INDEX) ||
 	    (i == ATOM_DEVICE_TV2_INDEX) ||
-            (i == ATOM_DEVICE_CV_INDEX))
-            info->BiosConnector[i].ddc_line = 0;
+	    (i == ATOM_DEVICE_CV_INDEX))
+	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
 	else
-	    info->BiosConnector[i].ddc_line =
-	        RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
+	    info->BiosConnector[i].ddc_i2c =
+		RADEONLookupGPIOLineForDDC(pScrn, ci.sucI2cId.sbfAccess.bfI2C_LineMux);
 
 	if (i == ATOM_DEVICE_DFP1_INDEX)
 	    info->BiosConnector[i].TMDSType = TMDS_INT;
@@ -1799,7 +1799,7 @@ RADEONGetATOMConnectorInfoFromBIOSConnectorTable (ScrnInfoPtr pScrn)
     for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
 	if (info->BiosConnector[i].valid) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d, hpd_mask-0x%x\n",
-		       i, (unsigned int)info->BiosConnector[i].ddc_line, info->BiosConnector[i].DACType,
+		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
 		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType,
 		       info->BiosConnector[i].hpd_mask);
 	}
diff --git a/src/radeon_bios.c b/src/radeon_bios.c
index 46f4a3b..8e6bd8d 100644
--- a/src/radeon_bios.c
+++ b/src/radeon_bios.c
@@ -74,7 +74,8 @@ Bool RADEONGetBIOSInfo(ScrnInfoPtr pScrn, xf86Int10InfoPtr  pInt10)
     unsigned short dptr;
 
 #ifdef XSERVER_LIBPCIACCESS
-    info->VBIOS = xalloc(info->PciInfo->rom_size);
+    //info->VBIOS = xalloc(info->PciInfo->rom_size);
+    info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
 #else
     info->VBIOS = xalloc(RADEON_VBIOS_SIZE);
 #endif
@@ -260,24 +261,28 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[i].valid = FALSE;
 		break;
 	    }
+
+	    info->BiosConnector[i].ddc_i2c.valid = FALSE;
+
 	    DDCType = (tmp >> 8) & 0xf;
 	    switch (DDCType) {
 	    case DDC_MONID:
-		info->BiosConnector[i].ddc_line = RADEON_GPIO_MONID;
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 		break;
 	    case DDC_DVI:
-		info->BiosConnector[i].ddc_line = RADEON_GPIO_DVI_DDC;
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 		break;
 	    case DDC_VGA:
-		info->BiosConnector[i].ddc_line = RADEON_GPIO_VGA_DDC;
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		break;
 	    case DDC_CRT2:
-		info->BiosConnector[i].ddc_line = RADEON_GPIO_CRT2_DDC;
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 		break;
 	    default:
 		xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
 		break;
 	    }
+
 	    if (tmp & 0x1)
 		info->BiosConnector[i].DACType = DAC_TVDAC;
 	    else
@@ -299,8 +304,8 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	     */
 	    if (info->ChipFamily == CHIP_FAMILY_RS400 &&
 		info->BiosConnector[i].ConnectorType == CONNECTOR_VGA &&
-		info->BiosConnector[i].ddc_line == RADEON_GPIO_CRT2_DDC) {
-		info->BiosConnector[i].ddc_line = RADEON_GPIO_MONID;
+		info->BiosConnector[i].ddc_i2c.mask_clk_reg == RADEON_GPIO_CRT2_DDC) {
+		info->BiosConnector[i].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    }
 
 	    /* XPRESS desktop chips seem to have a proprietary connector listed for
@@ -329,7 +334,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[0].DACType = DAC_PRIMARY;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
-	    info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	} else
 	    return FALSE;
     }
@@ -342,6 +347,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 	    info->BiosConnector[4].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[4].DACType = DAC_NONE;
 	    info->BiosConnector[4].TMDSType = TMDS_NONE;
+	    info->BiosConnector[4].ddc_i2c.valid = FALSE;
 
 	    tmp = RADEON_BIOS16(info->ROMHeaderStart + 0x42);
 	    if (tmp) {
@@ -352,26 +358,38 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 			DDCType	= tmp1;
 			switch (DDCType) {
 			case DDC_MONID:
-			    info->BiosConnector[4].ddc_line = RADEON_GPIO_MONID;
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 			    break;
 			case DDC_DVI:
-			    info->BiosConnector[4].ddc_line = RADEON_GPIO_DVI_DDC;
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 			    break;
 			case DDC_VGA:
-			    info->BiosConnector[4].ddc_line = RADEON_GPIO_VGA_DDC;
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 			    break;
 			case DDC_CRT2:
-			    info->BiosConnector[4].ddc_line = RADEON_GPIO_CRT2_DDC;
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 			    break;
 			case DDC_LCD:
-			    info->BiosConnector[4].ddc_line = RADEON_LCD_GPIO_MASK;
-			    info->BiosConnector[4].ddc_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
-			    info->BiosConnector[4].ddc_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
+			    info->BiosConnector[4].ddc_i2c.mask_clk_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.mask_data_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.get_data_mask = RADEON_BIOS32(tmp0 + 0x07);
 			    break;
 			case DDC_GPIO:
-			    info->BiosConnector[4].ddc_line = RADEON_MDGPIO_EN_REG;
-			    info->BiosConnector[4].ddc_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
-			    info->BiosConnector[4].ddc_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c = legacy_setup_i2c_bus(RADEON_MDGPIO_EN_REG);
+			    info->BiosConnector[4].ddc_i2c.mask_clk_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.mask_data_mask =
+				RADEON_BIOS32(tmp0 + 0x03) | RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.put_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.put_data_mask = RADEON_BIOS32(tmp0 + 0x07);
+			    info->BiosConnector[4].ddc_i2c.get_clk_mask = RADEON_BIOS32(tmp0 + 0x03);
+			    info->BiosConnector[4].ddc_i2c.get_data_mask = RADEON_BIOS32(tmp0 + 0x07);
 			    break;
 			default:
 			    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unknown DDC Type: %d\n", DDCType);
@@ -381,7 +399,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		    }
 		}
 	    } else {
-		info->BiosConnector[4].ddc_line = 0;
+		info->BiosConnector[4].ddc_i2c.valid = FALSE;
 	    }
 	}
     }
@@ -396,7 +414,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
 		info->BiosConnector[5].ConnectorType = CONNECTOR_STV;
 		info->BiosConnector[5].DACType = DAC_TVDAC;
 		info->BiosConnector[5].TMDSType = TMDS_NONE;
-		info->BiosConnector[5].ddc_line = 0;
+		info->BiosConnector[5].ddc_i2c.valid = FALSE;
 	    }
 	}
     }
@@ -405,7 +423,7 @@ static Bool RADEONGetLegacyConnectorInfoFromBIOS (ScrnInfoPtr pScrn)
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	if (info->BiosConnector[i].valid) {
 	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Port%d: DDCType-0x%x, DACType-%d, TMDSType-%d, ConnectorType-%d\n",
-		       i, (unsigned int)info->BiosConnector[i].ddc_line, info->BiosConnector[i].DACType,
+		       i, (unsigned int)info->BiosConnector[i].ddc_i2c.mask_clk_reg, info->BiosConnector[i].DACType,
 		       info->BiosConnector[i].TMDSType, info->BiosConnector[i].ConnectorType);
 	}
     }
@@ -875,19 +893,19 @@ Bool RADEONGetExtTMDSInfoFromBIOS (xf86OutputPtr output)
 	    table_start = offset+4;
 	    max_freq = RADEON_BIOS16(table_start);
 	    radeon_output->dvo_i2c_slave_addr = RADEON_BIOS8(table_start+2);
+	    radeon_output->dvo_i2c.valid = FALSE;
 	    gpio_reg = RADEON_BIOS8(table_start+3);
 	    if (gpio_reg == 1)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    else if (gpio_reg == 2)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_DVI_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	    else if (gpio_reg == 3)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_VGA_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	    else if (gpio_reg == 4)
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	    else if (gpio_reg == 5)
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "unsupported MM gpio_reg\n");
-		/*radeon_output->i2c_reg = RADEON_GPIO_MM;*/
 	    else {
 		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 			   "Unknown gpio reg: %d\n", gpio_reg);
diff --git a/src/radeon_output.c b/src/radeon_output.c
index ccfb4c5..5ef864e 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -206,7 +206,7 @@ void RADEONPrintPortMap(ScrnInfoPtr pScrn)
 		   ConnectorTypeName[radeon_output->ConnectorType],
 		   DACTypeName[radeon_output->DACType],
 		   TMDSTypeName[radeon_output->TMDSType],
-		   (unsigned int)radeon_output->ddc_line);
+		   (unsigned int)radeon_output->ddc_i2c.mask_clk_reg);
     }
 
 }
@@ -240,7 +240,7 @@ avivo_display_ddc_connected(ScrnInfoPtr pScrn, xf86OutputPtr output)
     } else MonType = MT_NONE;
     
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "DDC Type: 0x%x, Detected Monitor Type: %d\n", (unsigned int)radeon_output->ddc_line, MonType);
+	       "Output: %s, Detected Monitor Type: %d\n", output->name, MonType);
 
     return MonType;
 }
@@ -256,7 +256,10 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     int i, j;
 
-    DDCReg = radeon_output->ddc_line;
+    if (!radeon_output->ddc_i2c.valid)
+	return MT_NONE;
+
+    DDCReg = radeon_output->ddc_i2c.mask_clk_reg;
 
     /* Read and output monitor info using DDC2 over I2C bus */
     if (radeon_output->pI2CBus && info->ddc2 && (DDCReg != RADEON_LCD_GPIO_MASK) && (DDCReg != RADEON_MDGPIO_EN_REG)) {
@@ -340,7 +343,7 @@ RADEONDisplayDDCConnected(ScrnInfoPtr pScrn, xf86OutputPtr output)
     } else MonType = MT_NONE;
 
     xf86DrvMsg(pScrn->scrnIndex, X_INFO,
-	       "DDC Type: 0x%x, Detected Monitor Type: %d\n", (unsigned int)radeon_output->ddc_line, MonType);
+	       "Output: %s, Detected Monitor Type: %d\n", output->name, MonType);
 
     return MonType;
 }
@@ -1273,13 +1276,21 @@ Bool AVIVOI2CDoLock(xf86OutputPtr output, int lock_state)
     unsigned char *RADEONMMIO = info->MMIO;
     CARD32 temp;
 
-    temp = INREG(pRADEONI2CBus->gpio_reg);
+    temp = INREG(pRADEONI2CBus->mask_clk_reg);
+    if (lock_state == AVIVO_I2C_ENABLE)
+	temp |= (pRADEONI2CBus->put_clk_mask);
+    else
+	temp &= ~(pRADEONI2CBus->put_clk_mask);
+    OUTREG(pRADEONI2CBus->mask_clk_reg, temp);
+    temp = INREG(pRADEONI2CBus->mask_clk_reg);
+
+    temp = INREG(pRADEONI2CBus->mask_data_reg);
     if (lock_state == AVIVO_I2C_ENABLE)
-	temp |= (pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);
+	temp |= (pRADEONI2CBus->put_data_mask);
     else
-	temp &= ~(pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);;
-    OUTREG(pRADEONI2CBus->gpio_reg, temp);
-    temp = INREG(pRADEONI2CBus->gpio_reg);
+	temp &= ~(pRADEONI2CBus->put_data_mask);
+    OUTREG(pRADEONI2CBus->mask_data_reg, temp);
+    temp = INREG(pRADEONI2CBus->mask_data_reg);
 
     return TRUE;
 }
@@ -1293,9 +1304,11 @@ static void RADEONI2CGetBits(I2CBusPtr b, int *Clock, int *data)
     RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
 
     /* Get the result */
-    val = INREG(pRADEONI2CBus->get_reg);
+    val = INREG(pRADEONI2CBus->get_clk_reg);
     *Clock = (val & pRADEONI2CBus->get_clk_mask) != 0;
+    val = INREG(pRADEONI2CBus->get_data_reg);
     *data  = (val & pRADEONI2CBus->get_data_mask) != 0;
+
 }
 
 static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
@@ -1306,20 +1319,24 @@ static void RADEONI2CPutBits(I2CBusPtr b, int Clock, int data)
     unsigned char *RADEONMMIO = info->MMIO;
     RADEONI2CBusPtr pRADEONI2CBus = b->DriverPrivate.ptr;
 
-    val = INREG(pRADEONI2CBus->put_reg) & (CARD32)~(pRADEONI2CBus->put_clk_mask | pRADEONI2CBus->put_data_mask);
+    val = INREG(pRADEONI2CBus->put_clk_reg) & (CARD32)~(pRADEONI2CBus->put_clk_mask);
     val |= (Clock ? 0:pRADEONI2CBus->put_clk_mask);
-    val |= (data ? 0:pRADEONI2CBus->put_data_mask);
-    OUTREG(pRADEONI2CBus->put_reg, val);
+    OUTREG(pRADEONI2CBus->put_clk_reg, val);
+    /* read back to improve reliability on some cards. */
+    val = INREG(pRADEONI2CBus->put_clk_reg);
 
+    val = INREG(pRADEONI2CBus->put_data_reg) & (CARD32)~(pRADEONI2CBus->put_data_mask);
+    val |= (data ? 0:pRADEONI2CBus->put_data_mask);
+    OUTREG(pRADEONI2CBus->put_data_reg, val);
     /* read back to improve reliability on some cards. */
-    val = INREG(pRADEONI2CBus->put_reg);
+    val = INREG(pRADEONI2CBus->put_data_reg);
+
 }
 
 static Bool
 RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
 {
     ScrnInfoPtr pScrn = output->scrn;
-    RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     I2CBusPtr pI2CBus;
     RADEONI2CBusPtr pRADEONI2CBus;
@@ -1333,55 +1350,10 @@ RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
     pI2CBus->I2CGetBits = RADEONI2CGetBits;
     pI2CBus->AcknTimeout = 5;
 
-    pRADEONI2CBus = xcalloc(sizeof(RADEONI2CBusRec), 1);
-    if (!pRADEONI2CBus) {
-	xf86DrvMsg(pScrn->scrnIndex,X_ERROR, "Failed to allocate radeon i2c bus info\n");
-	return FALSE;
-    }
-
     if (dvo) {
-	/* these only seem to work properly on MACs */
-	pRADEONI2CBus->gpio_reg = radeon_output->dvo_i2c_reg;
-	pRADEONI2CBus->put_reg = radeon_output->dvo_i2c_reg;
-	pRADEONI2CBus->get_reg = radeon_output->dvo_i2c_reg;
-	pRADEONI2CBus->put_clk_mask = RADEON_GPIO_EN_1;
-	pRADEONI2CBus->put_data_mask = RADEON_GPIO_EN_0;
-	pRADEONI2CBus->get_clk_mask = RADEON_GPIO_Y_1;
-	pRADEONI2CBus->get_data_mask = RADEON_GPIO_Y_0;
+	pRADEONI2CBus = &(radeon_output->dvo_i2c);
     } else {
-	if (IS_AVIVO_VARIANT) {
-	    pRADEONI2CBus->gpio_reg = radeon_output->ddc_line;
-	    pRADEONI2CBus->put_reg = radeon_output->ddc_line + 0x8;
-	    pRADEONI2CBus->get_reg = radeon_output->ddc_line + 0xc;
-	    /* FIXME: get these from the BIOS */
-	    if (radeon_output->ddc_line == AVIVO_GPIO_0) {
-		pRADEONI2CBus->put_clk_mask = (1 << 19);
-		pRADEONI2CBus->put_data_mask = (1 << 18);
-		pRADEONI2CBus->get_clk_mask = (1 << 19);
-		pRADEONI2CBus->get_data_mask = (1 << 18);
-	    } else {
-		pRADEONI2CBus->put_clk_mask = (1 << 0);
-		pRADEONI2CBus->put_data_mask = (1 << 8);
-		pRADEONI2CBus->get_clk_mask = (1 << 0);
-		pRADEONI2CBus->get_data_mask = (1 << 8);
-	    }
-	} else {
-	    pRADEONI2CBus->gpio_reg = radeon_output->ddc_line;
-	    pRADEONI2CBus->put_reg = radeon_output->ddc_line;
-	    pRADEONI2CBus->get_reg = radeon_output->ddc_line;
-	    if ((radeon_output->ddc_line == RADEON_LCD_GPIO_MASK) ||
-		(radeon_output->ddc_line == RADEON_MDGPIO_EN_REG)) {
-		pRADEONI2CBus->put_clk_mask = radeon_output->ddc_clk_mask;
-		pRADEONI2CBus->put_data_mask = radeon_output->ddc_data_mask;
-		pRADEONI2CBus->get_clk_mask = radeon_output->ddc_clk_mask;
-		pRADEONI2CBus->get_data_mask = radeon_output->ddc_data_mask;
-	    } else {
-		pRADEONI2CBus->put_clk_mask = RADEON_GPIO_EN_1;
-		pRADEONI2CBus->put_data_mask = RADEON_GPIO_EN_0;
-		pRADEONI2CBus->get_clk_mask = RADEON_GPIO_Y_1;
-		pRADEONI2CBus->get_data_mask = RADEON_GPIO_Y_0;
-	    }
-	}
+	pRADEONI2CBus = &(radeon_output->ddc_i2c);
     }
 
     pI2CBus->DriverPrivate.ptr = (pointer)pRADEONI2CBus;
@@ -1393,6 +1365,28 @@ RADEONI2CInit(xf86OutputPtr output, I2CBusPtr *bus_ptr, char *name, Bool dvo)
     return TRUE;
 }
 
+RADEONI2CBusRec
+legacy_setup_i2c_bus(int ddc_line)
+{
+    RADEONI2CBusRec i2c;
+
+    i2c.mask_clk_mask = RADEON_GPIO_EN_1 | RADEON_GPIO_Y_1;
+    i2c.mask_data_mask =  RADEON_GPIO_EN_0 | RADEON_GPIO_Y_0;
+    i2c.put_clk_mask = RADEON_GPIO_EN_1;
+    i2c.put_data_mask = RADEON_GPIO_EN_0;
+    i2c.get_clk_mask = RADEON_GPIO_Y_1;
+    i2c.get_data_mask = RADEON_GPIO_Y_0;
+    i2c.mask_clk_reg = ddc_line;
+    i2c.mask_data_reg = ddc_line;
+    i2c.put_clk_reg = ddc_line;
+    i2c.put_data_reg = ddc_line;
+    i2c.get_clk_reg = ddc_line;
+    i2c.get_data_reg = ddc_line;
+    i2c.valid = TRUE;
+
+    return i2c;
+}
+
 static void
 RADEONGetPanelInfoFromReg (xf86OutputPtr output)
 {
@@ -1717,11 +1711,6 @@ void RADEONInitConnector(xf86OutputPtr output)
     ScrnInfoPtr	    pScrn = output->scrn;
     RADEONInfoPtr  info       = RADEONPTR(pScrn);
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
-    char stmp[16];
-    char *name;
-    sprintf(stmp, "DDC_0x%x", (unsigned int)radeon_output->ddc_line);
-    name = xnfalloc(strlen(stmp) + 1);
-    strcpy(name, stmp);
 
     if (radeon_output->DACType == DAC_PRIMARY)
 	radeon_output->load_detection = 1; /* primary dac, only drives vga */
@@ -1744,11 +1733,11 @@ void RADEONInitConnector(xf86OutputPtr output)
 	radeon_output->rmx_type = RMX_OFF;
 	if ((!info->IsAtomBios) && radeon_output->TMDSType == TMDS_EXT) {
 #if defined(__powerpc__)
-	    radeon_output->dvo_i2c_reg = RADEON_GPIO_MONID;
+	    radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	    radeon_output->dvo_i2c_slave_addr = 0x70;
 #else
 	    if (!RADEONGetExtTMDSInfoFromBIOS(output)) {
-		radeon_output->dvo_i2c_reg = RADEON_GPIO_CRT2_DDC;
+		radeon_output->dvo_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 		radeon_output->dvo_i2c_slave_addr = 0x70;
 	    }
 #endif
@@ -1773,8 +1762,8 @@ void RADEONInitConnector(xf86OutputPtr output)
 	RADEONGetTVDacAdjInfo(output);
     }
 
-    if (radeon_output->ddc_line)
-	RADEONI2CInit(output, &radeon_output->pI2CBus, name, FALSE);
+    if (radeon_output->ddc_i2c.valid)
+	RADEONI2CInit(output, &radeon_output->pI2CBus, output->name, FALSE);
 
 }
 
@@ -1786,13 +1775,13 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 
     switch (info->MacModel) {
     case RADEON_MAC_IBOOK:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
@@ -1801,17 +1790,17 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_EXTERNAL:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_EXT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -1820,18 +1809,18 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
 
     case RADEON_MAC_POWERBOOK_INTERNAL:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -1840,17 +1829,17 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_POWERBOOK_VGA:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[1].DACType = DAC_PRIMARY;
 	info->BiosConnector[1].TMDSType = TMDS_INT;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
@@ -1859,11 +1848,11 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_MINI_EXTERNAL:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_CRT2_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].TMDSType = TMDS_EXT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
@@ -1872,11 +1861,11 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].ddc_line = 0;
+	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_MINI_INTERNAL:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_CRT2_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 	info->BiosConnector[0].DACType = DAC_TVDAC;
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
@@ -1885,17 +1874,17 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[1].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
-	info->BiosConnector[1].ddc_line = 0;
+	info->BiosConnector[1].ddc_i2c.valid = FALSE;
 	info->BiosConnector[1].valid = TRUE;
 	return TRUE;
     case RADEON_MAC_IMAC_G5_ISIGHT:
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_MONID;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID);
 	info->BiosConnector[0].DACType = DAC_NONE;
 	info->BiosConnector[0].TMDSType = TMDS_INT;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_D;
 	info->BiosConnector[0].valid = TRUE;
 
-	info->BiosConnector[1].ddc_line = RADEON_GPIO_DVI_DDC;
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	info->BiosConnector[1].DACType = DAC_TVDAC;
 	info->BiosConnector[1].TMDSType = TMDS_NONE;
 	info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
@@ -1904,7 +1893,7 @@ static Bool RADEONSetupAppleConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].valid = TRUE;
 	return TRUE;
     default:
@@ -1921,7 +1910,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
     RADEONEntPtr pRADEONEnt  = RADEONEntPriv(pScrn);
 
     if (!pRADEONEnt->HasCRTC2) {
-	info->BiosConnector[0].ddc_line = RADEON_GPIO_VGA_DDC;
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 	info->BiosConnector[0].DACType = DAC_PRIMARY;
 	info->BiosConnector[0].TMDSType = TMDS_NONE;
 	info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
@@ -1931,28 +1920,28 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 
     if (IS_AVIVO_VARIANT) {
 	if (info->IsMobility) {
-	    info->BiosConnector[0].ddc_line = 0x7e60;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(0x7e60);
 	    info->BiosConnector[0].DACType = DAC_NONE;
 	    info->BiosConnector[0].TMDSType = TMDS_NONE;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_LCD1_SUPPORT;
 	    info->BiosConnector[0].valid = TRUE;
 
-	    info->BiosConnector[1].ddc_line = 0x7e40;
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(0x7e40);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 	    info->BiosConnector[1].devices = ATOM_DEVICE_CRT1_SUPPORT;
 	    info->BiosConnector[1].valid = TRUE;
 	} else {
-	    info->BiosConnector[0].ddc_line = 0x7e50;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(0x7e50);
 	    info->BiosConnector[0].DACType = DAC_TVDAC;
 	    info->BiosConnector[0].TMDSType = TMDS_INT;
 	    info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 	    info->BiosConnector[0].devices = ATOM_DEVICE_CRT2_SUPPORT | ATOM_DEVICE_DFP1_SUPPORT;
 	    info->BiosConnector[0].valid = TRUE;
 
-	    info->BiosConnector[1].ddc_line = 0x7e40;
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(0x7e40);
 	    info->BiosConnector[1].DACType = DAC_PRIMARY;
 	    info->BiosConnector[1].TMDSType = TMDS_NONE;
 	    info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
@@ -1963,14 +1952,14 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	info->BiosConnector[2].DACType = DAC_TVDAC;
 	info->BiosConnector[2].TMDSType = TMDS_NONE;
-	info->BiosConnector[2].ddc_line = 0;
+	info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	info->BiosConnector[2].devices = ATOM_DEVICE_TV1_SUPPORT;
 	info->BiosConnector[2].valid = TRUE;
     } else {
 	if (info->IsMobility) {
 	    /* Below is the most common setting, but may not be true */
 	    if (info->IsIGP) {
-		info->BiosConnector[0].ddc_line = RADEON_LCD_GPIO_MASK;
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
 		info->BiosConnector[0].DACType = DAC_NONE;
 		info->BiosConnector[0].TMDSType = TMDS_NONE;
 		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
@@ -1978,25 +1967,25 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 
 		/* IGP only has TVDAC */
 		if (info->ChipFamily == CHIP_FAMILY_RS400)
-		    info->BiosConnector[1].ddc_line = RADEON_GPIO_CRT2_DDC;
+		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 		else
-		    info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+		    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		info->BiosConnector[1].DACType = DAC_TVDAC;
 		info->BiosConnector[1].TMDSType = TMDS_NONE;
 		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
 		info->BiosConnector[1].valid = TRUE;
 	    } else {
 #if defined(__powerpc__)
-		info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 #else
-		info->BiosConnector[0].ddc_line = RADEON_LCD_GPIO_MASK;
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_LCD_GPIO_MASK);
 #endif
 		info->BiosConnector[0].DACType = DAC_NONE;
 		info->BiosConnector[0].TMDSType = TMDS_NONE;
 		info->BiosConnector[0].ConnectorType = CONNECTOR_LVDS;
 		info->BiosConnector[0].valid = TRUE;
 
-		info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		info->BiosConnector[1].DACType = DAC_PRIMARY;
 		info->BiosConnector[1].TMDSType = TMDS_NONE;
 		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
@@ -2006,9 +1995,9 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	    /* Below is the most common setting, but may not be true */
 	    if (info->IsIGP) {
 		if (info->ChipFamily == CHIP_FAMILY_RS400)
-		    info->BiosConnector[0].ddc_line = RADEON_GPIO_CRT2_DDC;
+		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
 		else
-		    info->BiosConnector[0].ddc_line = RADEON_GPIO_VGA_DDC;
+		    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		info->BiosConnector[0].DACType = DAC_TVDAC;
 		info->BiosConnector[0].TMDSType = TMDS_NONE;
 		info->BiosConnector[0].ConnectorType = CONNECTOR_VGA;
@@ -2017,26 +2006,26 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 		/* not sure what a good default DDCType for DVI on
 		 * IGP desktop chips is
 		 */
-		info->BiosConnector[1].ddc_line = RADEON_GPIO_MONID; /* DDC_DVI? */
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_MONID); /* DDC_DVI? */
 		info->BiosConnector[1].DACType = DAC_NONE;
 		info->BiosConnector[1].TMDSType = TMDS_EXT;
 		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_D;
 		info->BiosConnector[1].valid = TRUE;
 	    } else {
-		info->BiosConnector[0].ddc_line = RADEON_GPIO_DVI_DDC;
+		info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 		info->BiosConnector[0].DACType = DAC_TVDAC;
 		info->BiosConnector[0].TMDSType = TMDS_INT;
 		info->BiosConnector[0].ConnectorType = CONNECTOR_DVI_I;
 		info->BiosConnector[0].valid = TRUE;
 
 #if defined(__powerpc__)
-		info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		info->BiosConnector[1].DACType = DAC_PRIMARY;
 		info->BiosConnector[1].TMDSType = TMDS_EXT;
 		info->BiosConnector[1].ConnectorType = CONNECTOR_DVI_I;
 		info->BiosConnector[1].valid = TRUE;
 #else
-		info->BiosConnector[1].ddc_line = RADEON_GPIO_VGA_DDC;
+		info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
 		info->BiosConnector[1].DACType = DAC_PRIMARY;
 		info->BiosConnector[1].TMDSType = TMDS_EXT;
 		info->BiosConnector[1].ConnectorType = CONNECTOR_VGA;
@@ -2049,7 +2038,7 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	    info->BiosConnector[2].ConnectorType = CONNECTOR_STV;
 	    info->BiosConnector[2].DACType = DAC_TVDAC;
 	    info->BiosConnector[2].TMDSType = TMDS_NONE;
-	    info->BiosConnector[2].ddc_line = 0;
+	    info->BiosConnector[2].ddc_i2c.valid = FALSE;
 	    info->BiosConnector[2].valid = TRUE;
 	}
 
@@ -2057,8 +2046,8 @@ static void RADEONSetupGenericConnectors(ScrnInfoPtr pScrn)
 	 * detect it yet (Mac cards)
 	 */
 	if (xf86ReturnOptValBool(info->Options, OPTION_REVERSE_DDC, FALSE)) {
-	    info->BiosConnector[0].ddc_line = RADEON_GPIO_VGA_DDC;
-	    info->BiosConnector[1].ddc_line = RADEON_GPIO_DVI_DDC;
+	    info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
+	    info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
 	}
     }
 }
@@ -2198,7 +2187,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
      */
     for (i = 0; i < RADEON_MAX_BIOS_CONNECTOR; i++) {
 	info->BiosConnector[i].valid = FALSE;
-	info->BiosConnector[i].ddc_line = 0;
+	info->BiosConnector[i].ddc_i2c.valid = FALSE;
 	info->BiosConnector[i].DACType = DAC_NONE;
 	info->BiosConnector[i].TMDSType = TMDS_NONE;
 	info->BiosConnector[i].ConnectorType = CONNECTOR_NONE;
@@ -2280,8 +2269,8 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    return FALSE;
 	}
 
-	info->BiosConnector[0].ddc_line = ddc_line[0];
-	info->BiosConnector[1].ddc_line = ddc_line[1];
+	info->BiosConnector[0].ddc_i2c = legacy_setup_i2c_bus(ddc_line[0]);
+	info->BiosConnector[1].ddc_i2c = legacy_setup_i2c_bus(ddc_line[1]);
     }
 
     info->tvdac_use_count = 0;
@@ -2323,11 +2312,9 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn)
 	    }
 	    radeon_output->MonType = MT_UNKNOWN;
 	    radeon_output->ConnectorType = info->BiosConnector[i].ConnectorType;
-	    radeon_output->ddc_line = info->BiosConnector[i].ddc_line;
 	    radeon_output->devices = info->BiosConnector[i].devices;
 	    radeon_output->output_id = info->BiosConnector[i].output_id;
-	    radeon_output->ddc_clk_mask = info->BiosConnector[i].ddc_clk_mask;
-	    radeon_output->ddc_data_mask = info->BiosConnector[i].ddc_data_mask;
+	    radeon_output->ddc_i2c = info->BiosConnector[i].ddc_i2c;
 
 	    if (radeon_output->ConnectorType == CONNECTOR_DVI_D)
 		radeon_output->DACType = DAC_NONE;
diff --git a/src/radeon_probe.h b/src/radeon_probe.h
index 5dd1d00..df87dab 100644
--- a/src/radeon_probe.h
+++ b/src/radeon_probe.h
@@ -161,9 +161,15 @@ typedef enum
 
 typedef struct
 {
-    CARD32 gpio_reg;
-    CARD32 put_reg;
-    CARD32 get_reg;
+    Bool   valid;
+    CARD32 mask_clk_reg;
+    CARD32 mask_data_reg;
+    CARD32 put_clk_reg;
+    CARD32 put_data_reg;
+    CARD32 get_clk_reg;
+    CARD32 get_data_reg;
+    CARD32 mask_clk_mask;
+    CARD32 mask_data_mask;
     CARD32 put_clk_mask;
     CARD32 put_data_mask;
     CARD32 get_clk_mask;
@@ -193,7 +199,6 @@ typedef struct _RADEONCrtcPrivateRec {
 } RADEONCrtcPrivateRec, *RADEONCrtcPrivatePtr;
 
 typedef struct {
-    CARD32 ddc_line;
     RADEONDacType DACType;
     RADEONTmdsType TMDSType;
     RADEONConnectorType ConnectorType;
@@ -201,8 +206,7 @@ typedef struct {
     int output_id;
     int devices;
     int hpd_mask;
-    CARD32 ddc_clk_mask;
-    CARD32 ddc_data_mask;
+    RADEONI2CBusRec ddc_i2c;
 } RADEONBIOSConnector;
 
 typedef struct _RADEONOutputPrivateRec {
@@ -218,6 +222,7 @@ typedef struct _RADEONOutputPrivateRec {
     int crtc_num;
     int DDCReg;
     I2CBusPtr         pI2CBus;
+    RADEONI2CBusRec   ddc_i2c;
     CARD32            ps2_tvdac_adj;
     CARD32            pal_tvdac_adj;
     CARD32            ntsc_tvdac_adj;
@@ -237,7 +242,7 @@ typedef struct _RADEONOutputPrivateRec {
     RADEONRMXType     rmx_type;
     /* dvo */
     I2CDevPtr         DVOChip;
-    int               dvo_i2c_reg;
+    RADEONI2CBusRec   dvo_i2c;
     int               dvo_i2c_slave_addr;
     Bool              dvo_duallink;
     /* TV out */
@@ -251,9 +256,6 @@ typedef struct _RADEONOutputPrivateRec {
     Bool              tv_on;
     int               load_detection;
 
-    CARD32            ddc_clk_mask;
-    CARD32            ddc_data_mask;
-
     char              *name;
     int               output_id;
     int               devices;


More information about the xorg-commit mailing list