|
|
/******************************************************************************
* * ****************************************** * * Copyright (c) 1997, Cirrus Logic, Inc. * * * All Rights Reserved * * ****************************************** * * PROJECT: Laguna I (CL-GD546x) - * * FILE: clddc2b.c * * AUTHOR: Benny Ng * * DESCRIPTION: * This module checks for a DDC monitor, and returns the * established Timings value from the EDID if found. * **************************************************************************** ****************************************************************************/
/*----------------------------- INCLUDES ----------------------------------*/ #include "cirrus.h"
#define VOLATILE volatile
#define I2COUT_PORT 0x280
#define I2CIN_PORT 0x281
#define OFF 0
#define ON 1
/*-------------------------------------------------------------------------*/ unsigned char InMemb(PHW_DEVICE_EXTENSION HwDeviceExtension, int offset) { #undef LAGUNA_REGS
#define LAGUNA_REGS HwDeviceExtension->RegisterAddress
VOLATILE unsigned char *pByte = (unsigned char *)(LAGUNA_REGS + offset);
return *pByte; }
unsigned char OutMemb(PHW_DEVICE_EXTENSION HwDeviceExtension, int offset, unsigned char value) { #undef LAGUNA_REGS
#define LAGUNA_REGS HwDeviceExtension->RegisterAddress
VOLATILE unsigned char *pByte = (unsigned char *)(LAGUNA_REGS + offset);
*pByte = value; return *pByte; }
// NOTE: HwDeviceExtension->I2Cflavor determines whether to invert the
// output clock and data lines and is set in GetDDCInformation below
/*-------------------------------------------------------------------------*/ VOID WriteClockLine (PHW_DEVICE_EXTENSION HwDeviceExtension, UCHAR data) { UCHAR ReadSEQDATA;
ReadSEQDATA = InMemb(HwDeviceExtension, I2COUT_PORT);
ReadSEQDATA = (ReadSEQDATA & 0x7F) | ((data^HwDeviceExtension->I2Cflavor) << 7);
OutMemb(HwDeviceExtension, I2COUT_PORT, ReadSEQDATA); }
/*-------------------------------------------------------------------------*/ VOID WriteDataLine (PHW_DEVICE_EXTENSION HwDeviceExtension, UCHAR data) { UCHAR ReadSEQDATA;
ReadSEQDATA = InMemb(HwDeviceExtension, I2COUT_PORT);
ReadSEQDATA &= 0xFE; ReadSEQDATA |= (data^HwDeviceExtension->I2Cflavor) & 1;
OutMemb(HwDeviceExtension, I2COUT_PORT, ReadSEQDATA); }
/*-------------------------------------------------------------------------*/ BOOLEAN ReadClockLine (PHW_DEVICE_EXTENSION HwDeviceExtension) { UCHAR ReadSEQDATA;
ReadSEQDATA = InMemb(HwDeviceExtension, I2CIN_PORT);
return (ReadSEQDATA >> 7); }
/*-------------------------------------------------------------------------*/ BOOLEAN ReadDataLine (PHW_DEVICE_EXTENSION HwDeviceExtension) { return (InMemb(HwDeviceExtension, I2CIN_PORT) & 1); }
/*-------------------------------------------------------------------------*/ VOID WaitVSync (PHW_DEVICE_EXTENSION HwDeviceExtension) { // not used
}
// callbacks for VideoPortDDCMonitorHelper
I2C_FNC_TABLE I2CFunctions = { sizeof(struct _I2C_FNC_TABLE ), WriteClockLine, WriteDataLine, ReadClockLine, ReadDataLine, WaitVSync, NULL };
BOOLEAN GetDDCInformation( PHW_DEVICE_EXTENSION HwDeviceExtension, PVOID QueryBuffer, ULONG BufferSize ) { // Some cards invert the output clock and data bits.
// (It's probably all 5465's but since I'm not sure so I will try
// reading the DDC info first without inverting the output then with
// instead of assuming it by chip type)
HwDeviceExtension->I2Cflavor=0; // start non inverted
if (!VideoPortDDCMonitorHelper (HwDeviceExtension, &I2CFunctions, QueryBuffer, BufferSize) ) { HwDeviceExtension->I2Cflavor=0xff; // else try inverted
if (!VideoPortDDCMonitorHelper (HwDeviceExtension, &I2CFunctions, QueryBuffer, BufferSize) ) return FALSE; }
VideoPortMoveMemory(HwDeviceExtension->EDIDBuffer, QueryBuffer, sizeof(HwDeviceExtension->EDIDBuffer)); return TRUE; }
|