Move dvo driver detection into i830_dvo_init(), and use GPIOB for LVDS drivers.

The documentation states that GPIOB is (generally) used for devices on DVOA
on the motherboard, which appears to be the case on the laptop we have with
LVDS on the motherboard.

This patch is probably not entirely accurate, as there was apparently an LVDS
DVO card sold that could be put in desktop machines, which would likely be on
GPIOE like other ADD cards.  Given that we couldn't find one of these cards for
purchase, I'm not worrying about it.
This commit is contained in:
Eric Anholt 2006-12-21 16:21:28 -08:00
parent c87462ded2
commit b928cef9cd
1 changed files with 55 additions and 54 deletions

View File

@ -183,37 +183,6 @@ i830_dvo_detect(xf86OutputPtr output)
return intel_output->i2c_drv->vid_rec->detect(dev_priv);
}
static Bool
I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
struct _I830DVODriver **retdrv)
{
int i;
void *ret_ptr;
struct _I830DVODriver *drv;
for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) {
drv = &i830_dvo_drivers[i];
drv->modhandle = xf86LoadSubModule(pScrn, drv->modulename);
if (drv->modhandle == NULL)
continue;
xf86LoaderReqSymLists(drv->symbols, NULL);
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
if (drv->vid_rec != NULL)
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
drv->dev_priv = ret_ptr;
*retdrv = drv;
return TRUE;
}
xf86UnloadSubModule(drv->modhandle);
}
return FALSE;
}
static void
i830_dvo_destroy (xf86OutputPtr output)
{
@ -245,9 +214,14 @@ static const xf86OutputFuncsRec i830_dvo_output_funcs = {
void
i830_dvo_init(ScrnInfoPtr pScrn)
{
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
int ret;
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
int ret;
int i;
void *ret_ptr;
struct _I830DVODriver *drv;
int gpio_inited = 0;
I2CBusPtr pI2CBus = NULL;
output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
"TMDS");
@ -263,14 +237,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
output->driver_private = intel_output;
output->subpixel_order = SubPixelHorizontalRGB;
/* Set up the I2C and DDC buses */
ret = I830I2CInit(pScrn, &intel_output->pI2CBus, GPIOE, "DVOI2C_E");
if (!ret)
{
xf86OutputDestroy (output);
return;
}
/* Set up the DDC bus */
ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
if (!ret)
{
@ -279,17 +246,51 @@ i830_dvo_init(ScrnInfoPtr pScrn)
}
/* Now, try to find a controller */
ret = I830I2CDetectDVOControllers(pScrn, intel_output->pI2CBus,
&intel_output->i2c_drv);
if (ret)
{
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n",
intel_output->i2c_drv->modulename,
intel_output->pI2CBus->DriverPrivate.uval);
}
else
{
xf86OutputDestroy (output);
return;
for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) {
int gpio;
drv = &i830_dvo_drivers[i];
drv->modhandle = xf86LoadSubModule(pScrn, drv->modulename);
if (drv->modhandle == NULL)
continue;
xf86LoaderReqSymLists(drv->symbols, NULL);
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
if (drv->type & I830_DVO_CHIP_LVDS)
gpio = GPIOB;
else
gpio = GPIOE;
/* Set up the I2C bus necessary for the chip we're probing. It appears
* that everything is on GPIOE except for panels on i830 laptops, which
* are on GPIOB (DVOA).
*/
if (gpio_inited != gpio) {
if (pI2CBus != NULL)
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
if (!I830I2CInit(pScrn, &intel_output->pI2CBus, gpio,
gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E")) {
continue;
}
}
if (drv->vid_rec != NULL)
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
drv->dev_priv = ret_ptr;
intel_output->i2c_drv = drv;
intel_output->pI2CBus = pI2CBus;
return;
}
xf86UnloadSubModule(drv->modhandle);
}
/* Didn't find a chip, so tear down. */
if (pI2CBus != NULL)
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
xf86OutputDestroy (output);
}