Bool SMI_I2CInit(ScrnInfoPtr pScrn) { SMIPtr pSmi = SMIPTR(pScrn); if (pSmi->I2C == NULL) { I2CBusPtr I2CPtr = xf86CreateI2CBusRec(); if (I2CPtr == NULL) return FALSE; I2CPtr->BusName = "I2C bus"; I2CPtr->scrnIndex = pScrn->scrnIndex; I2CPtr->I2CPutBits = SMI_I2CPutBits; I2CPtr->I2CGetBits = SMI_I2CGetBits; if (!xf86I2CBusInit(I2CPtr)) { xf86DestroyI2CBusRec(I2CPtr, TRUE, TRUE); return FALSE; } pSmi->I2C = I2CPtr; } return TRUE; }
static void i830_dvo_destroy (xf86OutputPtr output) { I830OutputPrivatePtr intel_output = output->driver_private; if (intel_output) { if (intel_output->i2c_drv->vid_rec->destroy) intel_output->i2c_drv->vid_rec->destroy (intel_output->i2c_drv->dev_priv); if (intel_output->pI2CBus) xf86DestroyI2CBusRec (intel_output->pI2CBus, TRUE, TRUE); if (intel_output->pDDCBus) xf86DestroyI2CBusRec (intel_output->pDDCBus, TRUE, TRUE); free (intel_output); } }
void i830_dvo_init(ScrnInfoPtr scrn) { intel_screen_private *intel = intel_get_screen_private(scrn); I830OutputPrivatePtr intel_output; int ret; int i; void *ret_ptr; struct _I830DVODriver *drv; int gpio_inited = 0; I2CBusPtr pI2CBus = NULL; intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1); if (!intel_output) return; /* Set up the DDC bus */ ret = I830I2CInit(scrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D"); if (!ret) { free(intel_output); return; } /* Now, try to find a controller */ for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) { int gpio; drv = &i830_dvo_drivers[i]; drv->modhandle = xf86LoadSubModule(scrn, drv->modulename); if (drv->modhandle == NULL) continue; ret_ptr = NULL; drv->vid_rec = LoaderSymbol(drv->fntablename); if (!strcmp(drv->modulename, "ivch") && intel->quirk_flag & QUIRK_IVCH_NEED_DVOB) { drv->dvo_reg = DVOB; } /* Allow the I2C driver info to specify the GPIO to be used in * special cases, but otherwise default to what's defined in the spec. */ if (drv->gpio != 0) gpio = drv->gpio; else if (drv->type == I830_OUTPUT_DVO_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(scrn, &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) { xf86OutputPtr output = NULL; intel_output->type = drv->type; switch (drv->type) { case I830_OUTPUT_DVO_TMDS: intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) | (1 << I830_OUTPUT_DVO_TMDS)); output = xf86OutputCreate(scrn, &i830_dvo_output_funcs, "TMDS"); break; case I830_OUTPUT_DVO_LVDS: intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS); output = xf86OutputCreate(scrn, &i830_dvo_output_funcs, "LVDS"); break; case I830_OUTPUT_DVO_TVOUT: intel_output->pipe_mask = ((1 << 0) | (1 << 1)); intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT); output = xf86OutputCreate(scrn, &i830_dvo_output_funcs, "TV"); break; } if (output == NULL) { xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE); xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); free(intel_output); #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 xf86UnloadSubModule(drv->modhandle); #endif return; } output->driver_private = intel_output; output->subpixel_order = SubPixelHorizontalRGB; output->interlaceAllowed = FALSE; output->doubleScanAllowed = FALSE; drv->dev_priv = ret_ptr; intel_output->i2c_drv = drv; intel_output->pI2CBus = pI2CBus; if (intel_output->type == I830_OUTPUT_DVO_LVDS) { /* For our LVDS chipsets, we should hopefully be able to * dig the fixed panel mode out of the BIOS data. However, * it's in a different format from the BIOS data on chipsets * with integrated LVDS (stored in AIM headers, liekly), * so for now, just get the current mode being output through * DVO. */ intel->lvds_fixed_mode = i830_dvo_get_current_mode(output); intel->lvds_dither = TRUE; } return; } #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 12 xf86UnloadSubModule(drv->modhandle); #endif } /* Didn't find a chip, so tear down. */ if (pI2CBus != NULL) xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE); xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); free(intel_output); }