Give each output type an init method in its file, making other methods static.
This commit is contained in:
parent
103b4edce7
commit
ada8f62da2
14
src/i830.h
14
src/i830.h
|
|
@ -633,21 +633,13 @@ extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
|
|||
char *name);
|
||||
|
||||
/* i830_crt.c */
|
||||
void I830CRTDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
|
||||
void I830CRTSave(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
void I830CRTRestore(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
void i830_crt_init(ScrnInfoPtr pScrn);
|
||||
|
||||
/* i830_dvo.c */
|
||||
void I830DVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
|
||||
void I830DVOSave(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
void I830DVORestore(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
Bool I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
|
||||
struct _I830DVODriver **retdrv);
|
||||
void i830_dvo_init(ScrnInfoPtr pScrn);
|
||||
|
||||
/* i830_lvds.c */
|
||||
void I830LVDSDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
|
||||
void I830LVDSSave(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
void I830LVDSRestore(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
void i830_lvds_init(ScrnInfoPtr pScrn);
|
||||
|
||||
/* i830_memory.c */
|
||||
Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#include "xf86.h"
|
||||
#include "i830.h"
|
||||
|
||||
void
|
||||
I830CRTDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
static void
|
||||
i830_crt_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 temp;
|
||||
|
|
@ -58,18 +58,35 @@ I830CRTDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
|||
OUTREG(ADPA, temp);
|
||||
}
|
||||
|
||||
void
|
||||
I830CRTSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_crt_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
pI830->saveADPA = INREG(ADPA);
|
||||
}
|
||||
|
||||
void
|
||||
I830CRTRestore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_crt_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
OUTREG(ADPA, pI830->saveADPA);
|
||||
}
|
||||
|
||||
void
|
||||
i830_crt_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
pI830->output[pI830->num_outputs].type = I830_OUTPUT_ANALOG;
|
||||
pI830->output[pI830->num_outputs].dpms = i830_crt_dpms;
|
||||
pI830->output[pI830->num_outputs].save = i830_crt_save;
|
||||
pI830->output[pI830->num_outputs].restore = i830_crt_restore;
|
||||
|
||||
/* Set up the DDC bus. */
|
||||
I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
|
||||
GPIOA, "CRTDDC_A");
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,5 @@ void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
|
|||
void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);
|
||||
|
||||
/* i830_sdvo.c */
|
||||
I830SDVOPtr I830SDVOInit(ScrnInfoPtr pScrn, int output_index,
|
||||
CARD32 output_device);
|
||||
Bool I830SDVOPreSetMode(I830SDVOPtr s, DisplayModePtr mode);
|
||||
Bool I830SDVOPostSetMode(I830SDVOPtr s, DisplayModePtr mode);
|
||||
|
|
|
|||
|
|
@ -900,71 +900,30 @@ I830UseDDC(ScrnInfoPtr pScrn)
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set up the outputs according to what type of chip we are.
|
||||
*
|
||||
* Some outputs may not initialize, due to allocation failure or because a
|
||||
* controller chip isn't found.
|
||||
*/
|
||||
static void
|
||||
I830SetupOutputBusses(ScrnInfoPtr pScrn)
|
||||
I830SetupOutputs(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int i = 0;
|
||||
Bool ret;
|
||||
|
||||
/* everyone has at least a single analog output */
|
||||
pI830->output[i].type = I830_OUTPUT_ANALOG;
|
||||
pI830->output[i].dpms = I830CRTDPMS;
|
||||
pI830->output[i].save = I830CRTSave;
|
||||
pI830->output[i].restore = I830CRTRestore;
|
||||
i830_crt_init(pScrn);
|
||||
|
||||
/* setup the DDC bus for the analog output */
|
||||
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOA, "CRTDDC_A");
|
||||
i++;
|
||||
|
||||
if (IS_MOBILE(pI830) && !IS_I830(pI830)) {
|
||||
/* Set up integrated LVDS */
|
||||
pI830->output[i].type = I830_OUTPUT_LVDS;
|
||||
pI830->output[i].dpms = I830LVDSDPMS;
|
||||
pI830->output[i].save = I830LVDSSave;
|
||||
pI830->output[i].restore = I830LVDSRestore;
|
||||
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOC, "LVDSDDC_C");
|
||||
i++;
|
||||
}
|
||||
/* Set up integrated LVDS */
|
||||
if (IS_MOBILE(pI830) && !IS_I830(pI830))
|
||||
i830_lvds_init(pScrn);
|
||||
|
||||
if (IS_I9XX(pI830)) {
|
||||
/* Set up SDVOB */
|
||||
pI830->output[i].type = I830_OUTPUT_SDVO;
|
||||
pI830->output[i].dpms = i830SDVODPMS;
|
||||
pI830->output[i].save = i830SDVOSave;
|
||||
pI830->output[i].restore = i830SDVORestore;
|
||||
I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "SDVOCTRL_E");
|
||||
I830SDVOInit(pScrn, i, SDVOB);
|
||||
i++;
|
||||
|
||||
/* Set up SDVOC */
|
||||
pI830->output[i].type = I830_OUTPUT_SDVO;
|
||||
pI830->output[i].dpms = i830SDVODPMS;
|
||||
pI830->output[i].save = i830SDVOSave;
|
||||
pI830->output[i].restore = i830SDVORestore;
|
||||
pI830->output[i].pI2CBus = pI830->output[i-1].pI2CBus;
|
||||
I830SDVOInit(pScrn, i, SDVOC);
|
||||
i++;
|
||||
i830_sdvo_init(pScrn, SDVOB);
|
||||
i830_sdvo_init(pScrn, SDVOC);
|
||||
} else {
|
||||
/* set up DVO */
|
||||
pI830->output[i].type = I830_OUTPUT_DVO;
|
||||
pI830->output[i].dpms = I830DVODPMS;
|
||||
pI830->output[i].save = I830DVOSave;
|
||||
pI830->output[i].restore = I830DVORestore;
|
||||
I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOD, "DVODDC_D");
|
||||
I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
|
||||
|
||||
ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus,
|
||||
&pI830->output[i].i2c_drv);
|
||||
if (ret == TRUE) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n",
|
||||
pI830->output[i].i2c_drv->modulename,
|
||||
pI830->output[i].pI2CBus->DriverPrivate.uval);
|
||||
}
|
||||
|
||||
i++;
|
||||
i830_dvo_init(pScrn);
|
||||
}
|
||||
pI830->num_outputs = i;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -985,7 +944,7 @@ I830PreInitDDC(ScrnInfoPtr pScrn)
|
|||
if (xf86LoadSubModule(pScrn, "i2c")) {
|
||||
xf86LoaderReqSymLists(I810i2cSymbols, NULL);
|
||||
|
||||
I830SetupOutputBusses(pScrn);
|
||||
I830SetupOutputs(pScrn);
|
||||
|
||||
pI830->ddc2 = TRUE;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ struct _I830DVODriver i830_dvo_drivers[] =
|
|||
|
||||
#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver))
|
||||
|
||||
void
|
||||
I830DVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
static void
|
||||
i830_dvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
if (output->i2c_drv == NULL)
|
||||
return;
|
||||
|
|
@ -66,8 +66,8 @@ I830DVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
|||
output->i2c_drv->vid_rec->Power(output->i2c_drv->dev_priv, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
I830DVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_dvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
|
|
@ -84,8 +84,8 @@ I830DVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
output->i2c_drv->vid_rec->SaveRegs(output->i2c_drv->dev_priv);
|
||||
}
|
||||
|
||||
void
|
||||
I830DVORestore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_dvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
|
|
@ -129,3 +129,42 @@ I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
|
|||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
i830_dvo_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
Bool ret;
|
||||
int i = pI830->num_outputs;
|
||||
|
||||
pI830->output[i].type = I830_OUTPUT_DVO;
|
||||
pI830->output[i].dpms = i830_dvo_dpms;
|
||||
pI830->output[i].save = i830_dvo_save;
|
||||
pI830->output[i].restore = i830_dvo_restore;
|
||||
|
||||
/* Set up the I2C and DDC buses */
|
||||
ret = I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
|
||||
if (!ret)
|
||||
return;
|
||||
|
||||
ret = I830I2CInit(pScrn, &pI830->output[i].pDDCBus, GPIOD, "DVODDC_D");
|
||||
if (!ret) {
|
||||
xf86DestroyI2CBusRec(pI830->output[i].pI2CBus, TRUE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now, try to find a controller */
|
||||
ret = I830I2CDetectDVOControllers(pScrn, pI830->output[i].pI2CBus,
|
||||
&pI830->output[i].i2c_drv);
|
||||
if (ret) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n",
|
||||
pI830->output[i].i2c_drv->modulename,
|
||||
pI830->output[i].pI2CBus->DriverPrivate.uval);
|
||||
} else {
|
||||
xf86DestroyI2CBusRec(pI830->output[i].pI2CBus, TRUE, TRUE);
|
||||
xf86DestroyI2CBusRec(pI830->output[i].pDDCBus, TRUE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@
|
|||
#include "xf86.h"
|
||||
#include "i830.h"
|
||||
|
||||
void
|
||||
I830LVDSDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
static void
|
||||
i830_lvds_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
if (mode == DPMSModeOn)
|
||||
i830SetLVDSPanelPower(pScrn, TRUE);
|
||||
|
|
@ -41,8 +41,8 @@ I830LVDSDPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
|||
i830SetLVDSPanelPower(pScrn, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
I830LVDSSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_lvds_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
|
|
@ -66,8 +66,8 @@ I830LVDSSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
I830LVDSRestore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_lvds_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
|
|
@ -79,3 +79,22 @@ I830LVDSRestore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
OUTREG(LVDS, pI830->saveLVDS);
|
||||
OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
|
||||
}
|
||||
|
||||
void
|
||||
i830_lvds_init(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
pI830->output[pI830->num_outputs].type = I830_OUTPUT_LVDS;
|
||||
pI830->output[pI830->num_outputs].dpms = i830_lvds_dpms;
|
||||
pI830->output[pI830->num_outputs].save = i830_lvds_save;
|
||||
pI830->output[pI830->num_outputs].restore = i830_lvds_restore;
|
||||
|
||||
/* Set up the LVDS DDC channel. Most panels won't support it, but it can
|
||||
* be useful if available.
|
||||
*/
|
||||
I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
|
||||
GPIOC, "LVDSDDC_C");
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
236
src/i830_sdvo.c
236
src/i830_sdvo.c
|
|
@ -639,8 +639,22 @@ I830SDVOPostSetMode(I830SDVOPtr s, DisplayModePtr mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
i830SDVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_sdvo_dpms(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
I830SDVOPtr sdvo = output->sdvo_drv;
|
||||
|
||||
if (sdvo == NULL)
|
||||
return;
|
||||
|
||||
if (mode != DPMSModeOn)
|
||||
I830SDVOSetActiveOutputs(sdvo, FALSE, FALSE);
|
||||
else
|
||||
I830SDVOSetActiveOutputs(sdvo, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_sdvo_save(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830SDVOPtr sdvo = output->sdvo_drv;
|
||||
|
|
@ -679,23 +693,8 @@ i830SDVOSave(ScrnInfoPtr pScrn, I830OutputPtr output)
|
|||
sdvo->save_SDVOX = INREG(sdvo->output_device);
|
||||
}
|
||||
|
||||
void
|
||||
i830SDVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830SDVOPtr sdvo = output->sdvo_drv;
|
||||
|
||||
if (sdvo == NULL)
|
||||
return;
|
||||
|
||||
if (mode != DPMSModeOn)
|
||||
I830SDVOSetActiveOutputs(sdvo, FALSE, FALSE);
|
||||
else
|
||||
I830SDVOSetActiveOutputs(sdvo, TRUE, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
i830SDVORestore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
static void
|
||||
i830_sdvo_restore(ScrnInfoPtr pScrn, I830OutputPtr output)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830SDVOPtr sdvo = output->sdvo_drv;
|
||||
|
|
@ -827,95 +826,6 @@ I830SDVODDCI2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
I830SDVOPtr
|
||||
I830SDVOInit(ScrnInfoPtr pScrn, int output_index, CARD32 output_device)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830SDVOPtr sdvo;
|
||||
int i;
|
||||
unsigned char ch[0x40];
|
||||
I2CBusPtr i2cbus, ddcbus;
|
||||
|
||||
i2cbus = pI830->output[output_index].pI2CBus;
|
||||
|
||||
sdvo = xcalloc(1, sizeof(I830SDVORec));
|
||||
if (sdvo == NULL)
|
||||
return NULL;
|
||||
|
||||
if (output_device == SDVOB) {
|
||||
sdvo->d.DevName = "SDVO Controller B";
|
||||
sdvo->d.SlaveAddr = 0x70;
|
||||
} else {
|
||||
sdvo->d.DevName = "SDVO Controller C";
|
||||
sdvo->d.SlaveAddr = 0x72;
|
||||
}
|
||||
sdvo->d.pI2CBus = i2cbus;
|
||||
sdvo->d.DriverPrivate.ptr = sdvo;
|
||||
sdvo->output_device = output_device;
|
||||
|
||||
if (!xf86I2CDevInit(&sdvo->d)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Failed to initialize SDVO I2C device %s\n",
|
||||
output_device == SDVOB ? "SDVOB" : "SDVOC");
|
||||
xfree(sdvo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set up our wrapper I2C bus for DDC. It acts just like the regular I2C
|
||||
* bus, except that it does the control bus switch to DDC mode before every
|
||||
* Start. While we only need to do it at Start after every Stop after a
|
||||
* Start, extra attempts should be harmless.
|
||||
*/
|
||||
ddcbus = xf86CreateI2CBusRec();
|
||||
if (ddcbus == NULL) {
|
||||
xf86DestroyI2CDevRec(&sdvo->d, 0);
|
||||
xfree(sdvo);
|
||||
return NULL;
|
||||
}
|
||||
if (output_device == SDVOB)
|
||||
ddcbus->BusName = "SDVOB DDC Bus";
|
||||
else
|
||||
ddcbus->BusName = "SDVOC DDC Bus";
|
||||
ddcbus->scrnIndex = i2cbus->scrnIndex;
|
||||
ddcbus->I2CGetByte = I830SDVODDCI2CGetByte;
|
||||
ddcbus->I2CPutByte = I830SDVODDCI2CPutByte;
|
||||
ddcbus->I2CStart = I830SDVODDCI2CStart;
|
||||
ddcbus->I2CStop = I830SDVODDCI2CStop;
|
||||
ddcbus->I2CAddress = I830SDVODDCI2CAddress;
|
||||
ddcbus->DriverPrivate.ptr = sdvo;
|
||||
if (!xf86I2CBusInit(ddcbus)) {
|
||||
xf86DestroyI2CDevRec(&sdvo->d, 0);
|
||||
xfree(sdvo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pI830->output[output_index].pDDCBus = ddcbus;
|
||||
|
||||
/* Read the regs to test if we can talk to the device */
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if (!sReadByte(sdvo, i, &ch[i])) {
|
||||
xf86DestroyI2CBusRec(pI830->output[output_index].pDDCBus, FALSE,
|
||||
FALSE);
|
||||
xf86DestroyI2CDevRec(&sdvo->d, 0);
|
||||
xfree(sdvo);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pI830->output[output_index].sdvo_drv = sdvo;
|
||||
|
||||
I830SDVOGetCapabilities(sdvo, &sdvo->caps);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"SDVO device VID/DID: %02X:%02X.%02X, %02X, output 1: %c, output 2: %c\n",
|
||||
sdvo->caps.vendor_id, sdvo->caps.device_id,
|
||||
sdvo->caps.device_rev_id, sdvo->caps.caps,
|
||||
sdvo->caps.output_0_supported ? 'Y' : 'N',
|
||||
sdvo->caps.output_1_supported ? 'Y' : 'N');
|
||||
|
||||
return sdvo;
|
||||
}
|
||||
|
||||
static void
|
||||
I830DumpSDVOCmd (I830SDVOPtr s, int opcode)
|
||||
{
|
||||
|
|
@ -991,3 +901,113 @@ I830DetectSDVODisplays(ScrnInfoPtr pScrn, int output_index)
|
|||
return (s->sdvo_regs[SDVO_I2C_RETURN_0] != 0 ||
|
||||
s->sdvo_regs[SDVO_I2C_RETURN_1] != 0);
|
||||
}
|
||||
|
||||
void
|
||||
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830SDVOPtr sdvo;
|
||||
int i;
|
||||
unsigned char ch[0x40];
|
||||
I2CBusPtr i2cbus = NULL, ddcbus;
|
||||
|
||||
pI830->output[pI830->num_outputs].type = I830_OUTPUT_SDVO;
|
||||
pI830->output[pI830->num_outputs].dpms = i830_sdvo_dpms;
|
||||
pI830->output[pI830->num_outputs].save = i830_sdvo_save;
|
||||
pI830->output[pI830->num_outputs].restore = i830_sdvo_restore;
|
||||
|
||||
/* Find an existing SDVO I2CBus from another output, or allocate it. */
|
||||
for (i = 0; i < pI830->num_outputs; i++) {
|
||||
if (pI830->output[i].type == I830_OUTPUT_SDVO)
|
||||
i2cbus = pI830->output[i].pI2CBus;
|
||||
}
|
||||
if (i2cbus == NULL)
|
||||
I830I2CInit(pScrn, &i2cbus, GPIOE, "SDVOCTRL_E");
|
||||
if (i2cbus == NULL)
|
||||
return;
|
||||
|
||||
/* Allocate the SDVO output private data */
|
||||
sdvo = xcalloc(1, sizeof(I830SDVORec));
|
||||
if (sdvo == NULL) {
|
||||
xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (output_device == SDVOB) {
|
||||
sdvo->d.DevName = "SDVO Controller B";
|
||||
sdvo->d.SlaveAddr = 0x70;
|
||||
} else {
|
||||
sdvo->d.DevName = "SDVO Controller C";
|
||||
sdvo->d.SlaveAddr = 0x72;
|
||||
}
|
||||
sdvo->d.pI2CBus = i2cbus;
|
||||
sdvo->d.DriverPrivate.ptr = sdvo;
|
||||
sdvo->output_device = output_device;
|
||||
|
||||
if (!xf86I2CDevInit(&sdvo->d)) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Failed to initialize SDVO I2C device %s\n",
|
||||
output_device == SDVOB ? "SDVOB" : "SDVOC");
|
||||
xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
|
||||
xfree(sdvo);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up our wrapper I2C bus for DDC. It acts just like the regular I2C
|
||||
* bus, except that it does the control bus switch to DDC mode before every
|
||||
* Start. While we only need to do it at Start after every Stop after a
|
||||
* Start, extra attempts should be harmless.
|
||||
*/
|
||||
ddcbus = xf86CreateI2CBusRec();
|
||||
if (ddcbus == NULL) {
|
||||
xf86DestroyI2CDevRec(&sdvo->d, FALSE);
|
||||
xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
|
||||
xfree(sdvo);
|
||||
return;
|
||||
}
|
||||
if (output_device == SDVOB)
|
||||
ddcbus->BusName = "SDVOB DDC Bus";
|
||||
else
|
||||
ddcbus->BusName = "SDVOC DDC Bus";
|
||||
ddcbus->scrnIndex = i2cbus->scrnIndex;
|
||||
ddcbus->I2CGetByte = I830SDVODDCI2CGetByte;
|
||||
ddcbus->I2CPutByte = I830SDVODDCI2CPutByte;
|
||||
ddcbus->I2CStart = I830SDVODDCI2CStart;
|
||||
ddcbus->I2CStop = I830SDVODDCI2CStop;
|
||||
ddcbus->I2CAddress = I830SDVODDCI2CAddress;
|
||||
ddcbus->DriverPrivate.ptr = sdvo;
|
||||
if (!xf86I2CBusInit(ddcbus)) {
|
||||
xf86DestroyI2CDevRec(&sdvo->d, FALSE);
|
||||
xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
|
||||
xfree(sdvo);
|
||||
return;
|
||||
}
|
||||
|
||||
pI830->output[pI830->num_outputs].pI2CBus = ddcbus;
|
||||
pI830->output[pI830->num_outputs].pDDCBus = ddcbus;
|
||||
pI830->output[pI830->num_outputs].sdvo_drv = sdvo;
|
||||
|
||||
/* Read the regs to test if we can talk to the device */
|
||||
for (i = 0; i < 0x40; i++) {
|
||||
if (!sReadByte(sdvo, i, &ch[i])) {
|
||||
xf86DestroyI2CBusRec(pI830->output[pI830->num_outputs].pDDCBus,
|
||||
FALSE, FALSE);
|
||||
xf86DestroyI2CDevRec(&sdvo->d, FALSE);
|
||||
xf86DestroyI2CBusRec(i2cbus, TRUE, TRUE);
|
||||
xfree(sdvo);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
I830SDVOGetCapabilities(sdvo, &sdvo->caps);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"SDVO device VID/DID: %02X:%02X.%02X, %02X,"
|
||||
"output 1: %c, output 2: %c\n",
|
||||
sdvo->caps.vendor_id, sdvo->caps.device_id,
|
||||
sdvo->caps.device_rev_id, sdvo->caps.caps,
|
||||
sdvo->caps.output_0_supported ? 'Y' : 'N',
|
||||
sdvo->caps.output_1_supported ? 'Y' : 'N');
|
||||
|
||||
pI830->num_outputs++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,13 +56,7 @@ typedef struct _i830_sdvo_dtd {
|
|||
} __attribute__((packed)) i830_sdvo_dtd;
|
||||
|
||||
void
|
||||
i830SDVODPMS(ScrnInfoPtr pScrn, I830OutputPtr output, int mode);
|
||||
|
||||
void
|
||||
i830SDVOSave(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
|
||||
void
|
||||
i830SDVORestore(ScrnInfoPtr pScrn, I830OutputPtr output);
|
||||
i830_sdvo_init(ScrnInfoPtr pScrn, int output_device);
|
||||
|
||||
Bool
|
||||
I830DetectSDVODisplays(ScrnInfoPtr pScrn, int output_index);
|
||||
|
|
|
|||
Loading…
Reference in New Issue