diff options
Diffstat (limited to 'src/atimach64i2c.c')
-rw-r--r-- | src/atimach64i2c.c | 466 |
1 files changed, 0 insertions, 466 deletions
diff --git a/src/atimach64i2c.c b/src/atimach64i2c.c deleted file mode 100644 index 4cb565f6..00000000 --- a/src/atimach64i2c.c +++ /dev/null @@ -1,466 +0,0 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/atimach64i2c.c,v 1.1 2003/07/24 22:08:28 tsi Exp $ */ -/* - * Copyright 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting documentation, and - * that the name of Marc Aurele La France not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. Marc Aurele La France makes no representations - * about the suitability of this software for any purpose. It is provided - * "as-is" without express or implied warranty. - * - * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO - * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#include "ati.h" -#include "atichip.h" -#include "atii2c.h" -#include "atimach64i2c.h" -#include "atimach64io.h" -#include "atituner.h" - -/* MPP_CONFIG register values */ -#define MPP_INIT pATI->NewHW.mpp_config - -#define MPP_WRITE (MPP_INIT ) -#define MPP_WRITEINC (MPP_INIT | (MPP_AUTO_INC_EN )) -#define MPP_READ (MPP_INIT | ( MPP_BUFFER_MODE_PREFETCH)) -#define MPP_READINC (MPP_INIT | (MPP_AUTO_INC_EN | MPP_BUFFER_MODE_PREFETCH)) - -/* - * ATIMach64MPPWaitForIdle -- - * - * Support function to wait for the Multimedia Peripheral Port to become idle. - * Currently, this function's return value indicates whether or not the port - * became idle within 512 polling iterations. For now, this value is ignored - * by the rest of the code, but might be used in the future. - */ -static Bool -ATIMach64MPPWaitForIdle -( - ATIPtr pATI -) -{ - CARD32 Count = 0x0200; - - while (in8(MPP_CONFIG + 3) & GetByte(MPP_BUSY, 3)) - { - if (!--Count) - return FALSE; - usleep(1); /* XXX Excessive? */ - } - - return TRUE; -} - -/* - * ATIMach64MPPSetAddress -- - * - * Sets a 16-bit ImpacTV address on the Multimedia Peripheral Port. - */ -static void -ATIMach64MPPSetAddress -( - ATIPtr pATI, - CARD16 Address -) -{ - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_CONFIG, MPP_WRITEINC); - outr(MPP_ADDR, 0x00000008U); - out8(MPP_DATA, (CARD8)Address); - ATIMach64MPPWaitForIdle(pATI); - out8(MPP_DATA, (CARD8)(Address >> 8)); - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_CONFIG, MPP_WRITE); - outr(MPP_ADDR, 0x00000018U); - ATIMach64MPPWaitForIdle(pATI); -} - -/* - * ATIMach64ImpacTVProbe -- - * - * This probes for an ImpacTV chip and returns its chip ID, or 0. - */ -static int -ATIMach64ImpacTVProbe -( - int iScreen, - ATIPtr pATI -) -{ - CARD8 ChipID = 0; - - /* Assume ATIModePreInit() has already been called */ - outr(MPP_STROBE_SEQ, pATI->NewHW.mpp_strobe_seq); - outr(TVO_CNTL, pATI->NewHW.tvo_cntl); - - outr(MPP_CONFIG, MPP_READ); - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_ADDR, 0x0000000AU); - if (!(ChipID = in8(MPP_DATA))) - { - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_ADDR, 0x00000023U); - if ((ChipID = in8(MPP_DATA)) != 0x54U) - { - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_ADDR, 0x0000000BU); - ChipID = in8(MPP_DATA); - } - } - ATIMach64MPPWaitForIdle(pATI); - outr(MPP_CONFIG, MPP_WRITE); - - if (ChipID) - xf86DrvMsg(iScreen, X_PROBED, "ImpacTV chip ID 0x%02X detected.\n", - ChipID); - - return (int)(CARD16)ChipID; -} - -/* - * ATIMach64ImpacTVSetBits -- - * - * Controls I2C SDA and SCL lines through ImpacTV. - */ -static void -ATIMach64ImpacTVSetBits -( - ATII2CPtr pATII2C, - ATIPtr pATI, - CARD32 Bits -) -{ - pATII2C->I2CCur = Bits; - - ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); - - outr(MPP_CONFIG, MPP_WRITE); - - out8(MPP_DATA, (CARD8)Bits); - - ATIMach64MPPWaitForIdle(pATI); -} - -/* - * ATIMach64ImpacTVGetBits -- - * - * Returns the status of an ImpacTV's I2C control lines. - */ -static CARD32 -ATIMach64ImpacTVGetBits -( - ATIPtr pATI -) -{ - ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); - - outr(MPP_CONFIG, MPP_READ); - - ATIMach64MPPWaitForIdle(pATI); - - return in8(MPP_DATA); -} - -/* - * ATIMach64I2C_CNTLSetBits -- - * - * Controls SDA and SCL lines through a 3D Rage Pro's hardware assisted I2C. - */ -static void -ATIMach64I2C_CNTLSetBits -( - ATII2CPtr pATII2C, - ATIPtr pATI, - CARD32 Bits -) -{ - pATII2C->I2CCur = Bits; - - out8(I2C_CNTL_0 + 1, (CARD8)Bits); -} - -/* - * ATIMach64I2C_CNTLGetBits -- - * - * Returns the status of a 3D Rage Pro's hardware assisted I2C control lines. - */ -static CARD32 -ATIMach64I2C_CNTLGetBits -( - ATIPtr pATI -) -{ - return in8(I2C_CNTL_0 + 1); -} - -/* - * ATIMach64GP_IOSetBits -- - * - * Controls SDA and SCL control lines through a Mach64's GP_IO register. - */ -static void -ATIMach64GP_IOSetBits -( - ATII2CPtr pATII2C, - ATIPtr pATI, - CARD32 Bits -) -{ - pATII2C->I2CCur = Bits; - - outr(GP_IO, Bits); -} - -/* - * ATIMach64GP_IOGetBits -- - * - * Returns the status of I2C control lines through a Mach64's GP_IO register. - */ -static CARD32 -ATIMach64GP_IOGetBits -( - ATIPtr pATI -) -{ - return inr(GP_IO); -} - -#define GPIO1_MASK \ - (DAC_GIO_STATE_1 | DAC_GIO_DIR_1) -#define GPIO2_MASK \ - (GEN_GIO2_DATA_OUT | GEN_GIO2_DATA_IN | GEN_GIO2_WRITE) - -/* - * ATIMach64DAC_GENSetBits -- - * - * Controls SDA and SCL control lines through a Mach64's GEN_TEST_CNTL and - * DAC_CNTL registers. - */ -static void -ATIMach64DAC_GENSetBits -( - ATII2CPtr pATII2C, - ATIPtr pATI, - CARD32 Bits -) -{ - CARD32 tmp; - - pATII2C->I2CCur = Bits; - - tmp = inr(DAC_CNTL) & ~GPIO1_MASK; - outr(DAC_CNTL, tmp | (Bits & GPIO1_MASK)); - tmp = inr(GEN_TEST_CNTL) & ~GPIO2_MASK; - outr(GEN_TEST_CNTL, tmp | (Bits & GPIO2_MASK)); -} - -/* - * ATIMach64DAC_GENGetBits -- - * - * Returns the status of I2C control lines through a Mach64's GEN_TEST_CNTL and - * DAC_CNTL registers. - */ -static CARD32 -ATIMach64DAC_GENGetBits -( - ATIPtr pATI -) -{ - return (inr(DAC_CNTL) & GPIO1_MASK) | (inr(GEN_TEST_CNTL) & GPIO2_MASK); -} - -/* - * ATITVAddOnProbe -- - * - * Probe for an ATI-TV add-on card at specific addresses on an I2C bus. - */ -static Bool -ATITVAddOnProbe -( - ScrnInfoPtr pScreenInfo, - ATIPtr pATI, - I2CBusPtr pI2CBus -) -{ - I2CDevPtr pI2CDev = xnfcalloc(1, SizeOf(I2CDevRec)); - int Index; - I2CByte tmp; - - static const CARD8 ATITVAddOnAddresses[] = {0x70, 0x40, 0x78, 0x72, 0x42}; - - pI2CDev->DevName = "ATI-TV Add-on"; - pI2CDev->pI2CBus = pI2CBus; - pI2CDev->StartTimeout = pI2CBus->StartTimeout; - pI2CDev->BitTimeout = pI2CBus->BitTimeout; - pI2CDev->AcknTimeout = pI2CBus->AcknTimeout; - pI2CDev->ByteTimeout = pI2CBus->ByteTimeout; - - for (Index = 0; Index < NumberOf(ATITVAddOnAddresses); Index++) - { - pI2CDev->SlaveAddr = ATITVAddOnAddresses[Index]; - - if (xf86I2CFindDev(pI2CBus, pI2CDev->SlaveAddr)) - continue; - - tmp = 0xFFU; - - if (!(*pI2CBus->I2CWriteRead)(pI2CDev, &tmp, 1, NULL, 0) || - !(*pI2CBus->I2CWriteRead)(pI2CDev, NULL, 0, &tmp, 1) || - (tmp == 0xFFU) || ((tmp = tmp & 0x1FU) == /*ATI_TUNER_NONE*/0)) - continue; - - if (!xf86I2CDevInit(pI2CDev)) - { - xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, - "Failed to register I2C device for ATI-TV add-on.\n"); - break; - } - - if (pATI->Tuner != tmp) - { - if (pATI->Tuner != ATI_TUNER_NONE) - xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, - "Tuner type mismatch: BIOS 0x%x, ATI-TV 0x%x.\n", - pATI->Tuner, tmp); - - pATI->Tuner = tmp; - } - - xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, - "%s tuner detected on ATI-TV add-on adapter at I2C bus address" - " 0x%2x.\n", ATITuners[pATI->Tuner].name, pI2CDev->SlaveAddr); - - return TRUE; - } - - xfree(pI2CDev); - return FALSE; -} - -/* - * ATIMach64I2CPreInit -- - * - * This function potentially allocates an I2CBusRec and initialises it with - * ATI-specific and Mach64-specific information. - */ -void -ATIMach64I2CPreInit -( - ScrnInfoPtr pScreenInfo, - ATIPtr pATI -) -{ - I2CBusPtr pI2CBus; - ATII2CPtr pATII2C; - - if ((pATI->Chip < ATI_CHIP_264CT) || (pATI->Chip >= ATI_CHIP_Mach64)) - return; - - /* Create an I2CBusRec and generically prime it */ - if (!(pI2CBus = ATICreateI2CBusRec(pScreenInfo->scrnIndex, pATI, "Mach64"))) - return; - - pATII2C = pI2CBus->DriverPrivate.ptr; - - switch (pATI->Chip) - { - case ATI_CHIP_264GTPRO: - case ATI_CHIP_264LTPRO: - case ATI_CHIP_264XL: - case ATI_CHIP_MOBILITY: - /* - * These have I2C-specific registers. Assume older I2C access - * mechanisms are inoperative. - */ - pATII2C->I2CSetBits = ATIMach64I2C_CNTLSetBits; - pATII2C->I2CGetBits = ATIMach64I2C_CNTLGetBits; - pATII2C->SCLDir = pATII2C->SDADir = 0; - pATII2C->SCLGet = pATII2C->SCLSet = GetByte(I2C_CNTL_SCL, 1); - pATII2C->SDAGet = pATII2C->SDASet = GetByte(I2C_CNTL_SDA, 1); - - out8(I2C_CNTL_1 + 2, GetByte(I2C_SEL, 2)); - out8(I2C_CNTL_0 + 0, - GetByte(I2C_CNTL_STAT | I2C_CNTL_HPTR_RST, 0)); - break; - - case ATI_CHIP_264VTB: - case ATI_CHIP_264GTB: - case ATI_CHIP_264VT3: - case ATI_CHIP_264GTDVD: - case ATI_CHIP_264LT: - case ATI_CHIP_264VT4: - case ATI_CHIP_264GT2C: - /* If an ImpacTV chip is found, use it to provide I2C access */ - if (ATIMach64ImpacTVProbe(pScreenInfo->scrnIndex, pATI)) - { - pATII2C->I2CSetBits = ATIMach64ImpacTVSetBits; - pATII2C->I2CGetBits = ATIMach64ImpacTVGetBits; - pATII2C->SCLDir = IT_SCL_DIR; - pATII2C->SCLGet = IT_SCL_GET; - pATII2C->SCLSet = IT_SCL_SET; - pATII2C->SDADir = IT_SDA_DIR; - pATII2C->SDAGet = IT_SDA_GET; - pATII2C->SDASet = IT_SDA_SET; - - ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); - outr(MPP_CONFIG, MPP_WRITEINC); - out8(MPP_DATA, 0x00U); - out8(MPP_DATA, 0x55U); - out8(MPP_DATA, 0x00U); - out8(MPP_DATA, 0x00U); - ATIMach64MPPWaitForIdle(pATI); - break; - } - /* Otherwise, fall through to the older case */ - - case ATI_CHIP_264VT: - case ATI_CHIP_264GT: - /* First try GIO pins 11 (clock) and 4 (data) */ - pATII2C->I2CSetBits = ATIMach64GP_IOSetBits; - pATII2C->I2CGetBits = ATIMach64GP_IOGetBits; - pATII2C->SCLDir = GP_IO_DIR_B; - pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_B; - pATII2C->SDADir = GP_IO_DIR_4; - pATII2C->SDAGet = pATII2C->SDASet = GP_IO_4; - - if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus)) - break; - - /* Next, try pins 10 (clock) and 12 (data) */ - pATII2C->SCLDir = GP_IO_DIR_A; - pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_A; - pATII2C->SDADir = GP_IO_DIR_C; - pATII2C->SDAGet = pATII2C->SDASet = GP_IO_C; - - if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus)) - break; - /* Otherwise, fall back to ATI's first I2C implementation */ - - default: - /* - * First generation integrated controllers access GIO pin 1 (clock) - * though DAC_CNTL, and pin 2 (data) through GEN_TEST_CNTL. - */ - pATII2C->I2CSetBits = ATIMach64DAC_GENSetBits; - pATII2C->I2CGetBits = ATIMach64DAC_GENGetBits; - pATII2C->SCLDir = DAC_GIO_DIR_1; - pATII2C->SCLGet = pATII2C->SCLSet = DAC_GIO_STATE_1; - pATII2C->SDADir = GEN_GIO2_WRITE; - pATII2C->SDAGet = GEN_GIO2_DATA_IN; - pATII2C->SDASet = GEN_GIO2_DATA_OUT; - - (void)ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus); - break; - } -} |