void
cirProbeDDC(ScrnInfoPtr pScrn, int index)
{
    vbeInfoPtr pVbe;
    ModuleDescPtr pMod;

    if ((pMod = xf86LoadVBEModule(pScrn))) {
	xf86LoaderModReqSymLists(pMod, vbeSymbols,NULL);
        pVbe = VBEInit(NULL,index);
        ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
	vbeFree(pVbe);
	xf86UnloadSubModule(pMod);
    }
}
示例#2
0
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);
}