From fbba4312e7cb326fdcf6a71194c4fc4a7a9b5488 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 12 May 2006 18:44:27 +1000 Subject: [PATCH] add sdvo capability reading support This reads the SDVO cap bits and uses them to figure out the input/output to save/restore --- src/i830.h | 1 + src/i830_sdvo.c | 97 ++++++++++++++++++++++++++++++++++++------------- src/i830_sdvo.h | 11 ++++++ 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/src/i830.h b/src/i830.h index 7c4d50c8..c60bfbe6 100644 --- a/src/i830.h +++ b/src/i830.h @@ -194,6 +194,7 @@ typedef struct _I830SDVODriver { unsigned char sdvo_regs[20]; CARD32 output_device; /* SDVOB or SDVOC */ + i830_sdvo_caps caps; int save_sdvo_mult; Bool save_sdvo_active_1, save_sdvo_active_2; i830_sdvo_dtd save_input_dtd_1, save_input_dtd_2; diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c index 99cdc6ac..fe37d21a 100644 --- a/src/i830_sdvo.c +++ b/src/i830_sdvo.c @@ -579,19 +579,29 @@ i830SDVOSave(ScrnInfoPtr pScrn, int output_index) I830SDVOGetActiveOutputs(sdvo, &sdvo->save_sdvo_active_1, &sdvo->save_sdvo_active_2); - I830SDVOSetTargetInput(sdvo, TRUE, FALSE); - I830SDVOGetTimings(sdvo, &sdvo->save_input_dtd_1, - SDVO_CMD_GET_INPUT_TIMINGS_PART1); - I830SDVOSetTargetInput(sdvo, FALSE, TRUE); - I830SDVOGetTimings(sdvo, &sdvo->save_input_dtd_2, - SDVO_CMD_GET_INPUT_TIMINGS_PART1); + if (sdvo->caps.caps & 0x1) { + I830SDVOSetTargetInput(sdvo, TRUE, FALSE); + I830SDVOGetTimings(sdvo, &sdvo->save_input_dtd_1, + SDVO_CMD_GET_INPUT_TIMINGS_PART1); + } - I830SDVOSetTargetOutput(sdvo, TRUE, FALSE); - I830SDVOGetTimings(sdvo, &sdvo->save_output_dtd_1, - SDVO_CMD_GET_OUTPUT_TIMINGS_PART1); - I830SDVOSetTargetOutput(sdvo, FALSE, TRUE); - I830SDVOGetTimings(sdvo, &sdvo->save_output_dtd_2, - SDVO_CMD_GET_OUTPUT_TIMINGS_PART1); + if (sdvo->caps.caps & 0x2) { + I830SDVOSetTargetInput(sdvo, FALSE, TRUE); + I830SDVOGetTimings(sdvo, &sdvo->save_input_dtd_2, + SDVO_CMD_GET_INPUT_TIMINGS_PART1); + } + + if (sdvo->caps.output_0_supported) { + I830SDVOSetTargetOutput(sdvo, TRUE, FALSE); + I830SDVOGetTimings(sdvo, &sdvo->save_output_dtd_1, + SDVO_CMD_GET_OUTPUT_TIMINGS_PART1); + } + + if (sdvo->caps.output_1_supported) { + I830SDVOSetTargetOutput(sdvo, FALSE, TRUE); + I830SDVOGetTimings(sdvo, &sdvo->save_output_dtd_2, + SDVO_CMD_GET_OUTPUT_TIMINGS_PART1); + } sdvo->save_SDVOX = INREG(sdvo->output_device); } @@ -611,19 +621,29 @@ i830SDVOPostRestore(ScrnInfoPtr pScrn, int output_index) I830Ptr pI830 = I830PTR(pScrn); I830SDVOPtr sdvo = pI830->output[output_index].sdvo_drv; - I830SDVOSetTargetInput(sdvo, TRUE, FALSE); - I830SDVOSetTimings(sdvo, &sdvo->save_input_dtd_1, - SDVO_CMD_SET_INPUT_TIMINGS_PART1); - I830SDVOSetTargetInput(sdvo, FALSE, TRUE); - I830SDVOSetTimings(sdvo, &sdvo->save_input_dtd_2, - SDVO_CMD_SET_INPUT_TIMINGS_PART1); + if (sdvo->caps.caps & 0x1) { + I830SDVOSetTargetInput(sdvo, TRUE, FALSE); + I830SDVOSetTimings(sdvo, &sdvo->save_input_dtd_1, + SDVO_CMD_SET_INPUT_TIMINGS_PART1); + } - I830SDVOSetTargetOutput(sdvo, TRUE, FALSE); - I830SDVOSetTimings(sdvo, &sdvo->save_output_dtd_1, - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1); - I830SDVOSetTargetOutput(sdvo, FALSE, TRUE); - I830SDVOSetTimings(sdvo, &sdvo->save_output_dtd_2, - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1); + if (sdvo->caps.caps & 0x2) { + I830SDVOSetTargetInput(sdvo, FALSE, TRUE); + I830SDVOSetTimings(sdvo, &sdvo->save_input_dtd_2, + SDVO_CMD_SET_INPUT_TIMINGS_PART1); + } + + if (sdvo->caps.output_0_supported) { + I830SDVOSetTargetOutput(sdvo, TRUE, FALSE); + I830SDVOSetTimings(sdvo, &sdvo->save_output_dtd_1, + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1); + } + + if (sdvo->caps.output_1_supported) { + I830SDVOSetTargetOutput(sdvo, FALSE, TRUE); + I830SDVOSetTimings(sdvo, &sdvo->save_output_dtd_2, + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1); + } I830SDVOSetClockRateMult(sdvo, sdvo->save_sdvo_mult); @@ -633,6 +653,24 @@ i830SDVOPostRestore(ScrnInfoPtr pScrn, int output_index) sdvo->save_sdvo_active_2); } +static void +I830SDVOGetCapabilities(I830SDVOPtr s, i830_sdvo_caps *caps) +{ + memset(s->sdvo_regs, 0, 9); + s->sdvo_regs[SDVO_I2C_OPCODE] = SDVO_CMD_GET_DEVICE_CAPS; + I830SDVOWriteOutputs(s, 0); + I830SDVOReadInputRegs(s); + + caps->vendor_id = s->sdvo_regs[SDVO_I2C_RETURN_0]; + caps->device_id = s->sdvo_regs[SDVO_I2C_RETURN_1]; + caps->device_rev_id = s->sdvo_regs[SDVO_I2C_RETURN_2]; + caps->sdvo_version_major = s->sdvo_regs[SDVO_I2C_RETURN_3]; + caps->sdvo_version_minor = s->sdvo_regs[SDVO_I2C_RETURN_4]; + caps->caps = s->sdvo_regs[SDVO_I2C_RETURN_5]; + caps->output_0_supported = s->sdvo_regs[SDVO_I2C_RETURN_6]; + caps->output_1_supported = s->sdvo_regs[SDVO_I2C_RETURN_7]; +} + static Bool I830SDVODDCI2CGetByte(I2CDevPtr d, I2CByte *data, Bool last) { @@ -669,7 +707,7 @@ I830SDVODDCI2CStart(I2CBusPtr b, int timeout) I830SDVOPtr sdvo = b->DriverPrivate.ptr; I2CBusPtr i2cbus = sdvo->d.pI2CBus; - I830SDVOSetControlBusSwitch(sdvo, SDVO_CONTROL_BUS_DDC1); + I830SDVOSetControlBusSwitch(sdvo, SDVO_CONTROL_BUS_DDC2); return i2cbus->I2CStart(i2cbus, timeout); } @@ -781,5 +819,14 @@ I830SDVOInit(ScrnInfoPtr pScrn, int output_index, CARD32 output_device) 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; } diff --git a/src/i830_sdvo.h b/src/i830_sdvo.h index ec4b538b..6b77c97a 100644 --- a/src/i830_sdvo.h +++ b/src/i830_sdvo.h @@ -25,6 +25,17 @@ * */ +typedef struct _i830_sdvo_caps { + CARD8 vendor_id; + CARD8 device_id; + CARD8 device_rev_id; + CARD8 sdvo_version_major; + CARD8 sdvo_version_minor; + CARD8 caps; + CARD8 output_0_supported; + CARD8 output_1_supported; +} __attribute__((packed)) i830_sdvo_caps; + typedef struct _i830_sdvo_dtd { CARD16 clock; CARD8 h_active;