diff options
-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); } |