Give each output type an init method in its file, making other methods static.

This commit is contained in:
Eric Anholt 2006-10-05 15:55:07 -07:00
parent 103b4edce7
commit ada8f62da2
8 changed files with 240 additions and 202 deletions

View File

@ -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);

View File

@ -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++;
}

View File

@ -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);

View File

@ -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 {

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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++;
}

View File

@ -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);