diff options
author | Eric Anholt <eric@anholt.net> | 2006-12-21 16:21:28 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2006-12-28 11:41:46 -0800 |
commit | b928cef9cd5b3f88dc0880f406300d246a59e0fe (patch) | |
tree | 9e296cc289cf62715bb16a359a5b9d1d41e9bca4 | |
parent | c87462ded20904dbc6c6cbdb9547523b75fe5471 (diff) |
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.
-rw-r--r-- | src/i830_dvo.c | 109 |
1 files changed, 55 insertions, 54 deletions
diff --git a/src/i830_dvo.c b/src/i830_dvo.c index 97453ded..283e975b 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -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); } |