132b578d3Smrg/* 232b578d3Smrg * Copyright 2003 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org 332b578d3Smrg * 432b578d3Smrg * Permission to use, copy, modify, distribute, and sell this software and its 532b578d3Smrg * documentation for any purpose is hereby granted without fee, provided that 632b578d3Smrg * the above copyright notice appear in all copies and that both that copyright 732b578d3Smrg * notice and this permission notice appear in supporting documentation, and 832b578d3Smrg * that the name of Marc Aurele La France not be used in advertising or 932b578d3Smrg * publicity pertaining to distribution of the software without specific, 1032b578d3Smrg * written prior permission. Marc Aurele La France makes no representations 1132b578d3Smrg * about the suitability of this software for any purpose. It is provided 1232b578d3Smrg * "as-is" without express or implied warranty. 1332b578d3Smrg * 1432b578d3Smrg * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1532b578d3Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 1632b578d3Smrg * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1732b578d3Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1832b578d3Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1932b578d3Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2032b578d3Smrg * PERFORMANCE OF THIS SOFTWARE. 2132b578d3Smrg */ 2232b578d3Smrg 2332b578d3Smrg#ifdef HAVE_CONFIG_H 2432b578d3Smrg#include "config.h" 2532b578d3Smrg#endif 2632b578d3Smrg 2732b578d3Smrg#include "ati.h" 2832b578d3Smrg#include "atichip.h" 2932b578d3Smrg#include "atii2c.h" 3032b578d3Smrg#include "atimach64i2c.h" 3132b578d3Smrg#include "atimach64io.h" 3232b578d3Smrg#include "atituner.h" 3332b578d3Smrg 3432b578d3Smrg/* MPP_CONFIG register values */ 3532b578d3Smrg#define MPP_INIT pATI->NewHW.mpp_config 3632b578d3Smrg 3732b578d3Smrg#define MPP_WRITE (MPP_INIT ) 3832b578d3Smrg#define MPP_WRITEINC (MPP_INIT | (MPP_AUTO_INC_EN )) 3932b578d3Smrg#define MPP_READ (MPP_INIT | ( MPP_BUFFER_MODE_PREFETCH)) 4032b578d3Smrg#define MPP_READINC (MPP_INIT | (MPP_AUTO_INC_EN | MPP_BUFFER_MODE_PREFETCH)) 4132b578d3Smrg 4232b578d3Smrg/* 4332b578d3Smrg * ATIMach64MPPWaitForIdle -- 4432b578d3Smrg * 4532b578d3Smrg * Support function to wait for the Multimedia Peripheral Port to become idle. 4632b578d3Smrg * Currently, this function's return value indicates whether or not the port 4732b578d3Smrg * became idle within 512 polling iterations. For now, this value is ignored 4832b578d3Smrg * by the rest of the code, but might be used in the future. 4932b578d3Smrg */ 5032b578d3Smrgstatic Bool 5132b578d3SmrgATIMach64MPPWaitForIdle 5232b578d3Smrg( 5332b578d3Smrg ATIPtr pATI 5432b578d3Smrg) 5532b578d3Smrg{ 5632b578d3Smrg CARD32 Count = 0x0200; 5732b578d3Smrg 5832b578d3Smrg while (in8(MPP_CONFIG + 3) & GetByte(MPP_BUSY, 3)) 5932b578d3Smrg { 6032b578d3Smrg if (!--Count) 6132b578d3Smrg return FALSE; 6232b578d3Smrg usleep(1); /* XXX Excessive? */ 6332b578d3Smrg } 6432b578d3Smrg 6532b578d3Smrg return TRUE; 6632b578d3Smrg} 6732b578d3Smrg 6832b578d3Smrg/* 6932b578d3Smrg * ATIMach64MPPSetAddress -- 7032b578d3Smrg * 7132b578d3Smrg * Sets a 16-bit ImpacTV address on the Multimedia Peripheral Port. 7232b578d3Smrg */ 7332b578d3Smrgstatic void 7432b578d3SmrgATIMach64MPPSetAddress 7532b578d3Smrg( 7632b578d3Smrg ATIPtr pATI, 7732b578d3Smrg CARD16 Address 7832b578d3Smrg) 7932b578d3Smrg{ 8032b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 8132b578d3Smrg outr(MPP_CONFIG, MPP_WRITEINC); 8232b578d3Smrg outr(MPP_ADDR, 0x00000008U); 8332b578d3Smrg out8(MPP_DATA, (CARD8)Address); 8432b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 8532b578d3Smrg out8(MPP_DATA, (CARD8)(Address >> 8)); 8632b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 8732b578d3Smrg outr(MPP_CONFIG, MPP_WRITE); 8832b578d3Smrg outr(MPP_ADDR, 0x00000018U); 8932b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 9032b578d3Smrg} 9132b578d3Smrg 9232b578d3Smrg/* 9332b578d3Smrg * ATIMach64ImpacTVProbe -- 9432b578d3Smrg * 9532b578d3Smrg * This probes for an ImpacTV chip and returns its chip ID, or 0. 9632b578d3Smrg */ 9732b578d3Smrgstatic int 9832b578d3SmrgATIMach64ImpacTVProbe 9932b578d3Smrg( 10032b578d3Smrg int iScreen, 10132b578d3Smrg ATIPtr pATI 10232b578d3Smrg) 10332b578d3Smrg{ 10432b578d3Smrg CARD8 ChipID = 0; 10532b578d3Smrg 10632b578d3Smrg /* Assume ATIModePreInit() has already been called */ 10732b578d3Smrg outr(MPP_STROBE_SEQ, pATI->NewHW.mpp_strobe_seq); 10832b578d3Smrg outr(TVO_CNTL, pATI->NewHW.tvo_cntl); 10932b578d3Smrg 11032b578d3Smrg outr(MPP_CONFIG, MPP_READ); 11132b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 11232b578d3Smrg outr(MPP_ADDR, 0x0000000AU); 11332b578d3Smrg if (!(ChipID = in8(MPP_DATA))) 11432b578d3Smrg { 11532b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 11632b578d3Smrg outr(MPP_ADDR, 0x00000023U); 11732b578d3Smrg if ((ChipID = in8(MPP_DATA)) != 0x54U) 11832b578d3Smrg { 11932b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 12032b578d3Smrg outr(MPP_ADDR, 0x0000000BU); 12132b578d3Smrg ChipID = in8(MPP_DATA); 12232b578d3Smrg } 12332b578d3Smrg } 12432b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 12532b578d3Smrg outr(MPP_CONFIG, MPP_WRITE); 12632b578d3Smrg 12732b578d3Smrg if (ChipID) 12832b578d3Smrg xf86DrvMsg(iScreen, X_PROBED, "ImpacTV chip ID 0x%02X detected.\n", 12932b578d3Smrg ChipID); 13032b578d3Smrg 13132b578d3Smrg return (int)(CARD16)ChipID; 13232b578d3Smrg} 13332b578d3Smrg 13432b578d3Smrg/* 13532b578d3Smrg * ATIMach64ImpacTVSetBits -- 13632b578d3Smrg * 13732b578d3Smrg * Controls I2C SDA and SCL lines through ImpacTV. 13832b578d3Smrg */ 13932b578d3Smrgstatic void 14032b578d3SmrgATIMach64ImpacTVSetBits 14132b578d3Smrg( 14232b578d3Smrg ATII2CPtr pATII2C, 14332b578d3Smrg ATIPtr pATI, 14432b578d3Smrg CARD32 Bits 14532b578d3Smrg) 14632b578d3Smrg{ 14732b578d3Smrg pATII2C->I2CCur = Bits; 14832b578d3Smrg 14932b578d3Smrg ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); 15032b578d3Smrg 15132b578d3Smrg outr(MPP_CONFIG, MPP_WRITE); 15232b578d3Smrg 15332b578d3Smrg out8(MPP_DATA, (CARD8)Bits); 15432b578d3Smrg 15532b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 15632b578d3Smrg} 15732b578d3Smrg 15832b578d3Smrg/* 15932b578d3Smrg * ATIMach64ImpacTVGetBits -- 16032b578d3Smrg * 16132b578d3Smrg * Returns the status of an ImpacTV's I2C control lines. 16232b578d3Smrg */ 16332b578d3Smrgstatic CARD32 16432b578d3SmrgATIMach64ImpacTVGetBits 16532b578d3Smrg( 16632b578d3Smrg ATIPtr pATI 16732b578d3Smrg) 16832b578d3Smrg{ 16932b578d3Smrg ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); 17032b578d3Smrg 17132b578d3Smrg outr(MPP_CONFIG, MPP_READ); 17232b578d3Smrg 17332b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 17432b578d3Smrg 17532b578d3Smrg return in8(MPP_DATA); 17632b578d3Smrg} 17732b578d3Smrg 17832b578d3Smrg/* 17932b578d3Smrg * ATIMach64I2C_CNTLSetBits -- 18032b578d3Smrg * 18132b578d3Smrg * Controls SDA and SCL lines through a 3D Rage Pro's hardware assisted I2C. 18232b578d3Smrg */ 18332b578d3Smrgstatic void 18432b578d3SmrgATIMach64I2C_CNTLSetBits 18532b578d3Smrg( 18632b578d3Smrg ATII2CPtr pATII2C, 18732b578d3Smrg ATIPtr pATI, 18832b578d3Smrg CARD32 Bits 18932b578d3Smrg) 19032b578d3Smrg{ 19132b578d3Smrg pATII2C->I2CCur = Bits; 19232b578d3Smrg 19332b578d3Smrg out8(I2C_CNTL_0 + 1, (CARD8)Bits); 19432b578d3Smrg} 19532b578d3Smrg 19632b578d3Smrg/* 19732b578d3Smrg * ATIMach64I2C_CNTLGetBits -- 19832b578d3Smrg * 19932b578d3Smrg * Returns the status of a 3D Rage Pro's hardware assisted I2C control lines. 20032b578d3Smrg */ 20132b578d3Smrgstatic CARD32 20232b578d3SmrgATIMach64I2C_CNTLGetBits 20332b578d3Smrg( 20432b578d3Smrg ATIPtr pATI 20532b578d3Smrg) 20632b578d3Smrg{ 20732b578d3Smrg return in8(I2C_CNTL_0 + 1); 20832b578d3Smrg} 20932b578d3Smrg 21032b578d3Smrg/* 21132b578d3Smrg * ATIMach64GP_IOSetBits -- 21232b578d3Smrg * 21332b578d3Smrg * Controls SDA and SCL control lines through a Mach64's GP_IO register. 21432b578d3Smrg */ 21532b578d3Smrgstatic void 21632b578d3SmrgATIMach64GP_IOSetBits 21732b578d3Smrg( 21832b578d3Smrg ATII2CPtr pATII2C, 21932b578d3Smrg ATIPtr pATI, 22032b578d3Smrg CARD32 Bits 22132b578d3Smrg) 22232b578d3Smrg{ 22332b578d3Smrg pATII2C->I2CCur = Bits; 22432b578d3Smrg 22532b578d3Smrg outr(GP_IO, Bits); 22632b578d3Smrg} 22732b578d3Smrg 22832b578d3Smrg/* 22932b578d3Smrg * ATIMach64GP_IOGetBits -- 23032b578d3Smrg * 23132b578d3Smrg * Returns the status of I2C control lines through a Mach64's GP_IO register. 23232b578d3Smrg */ 23332b578d3Smrgstatic CARD32 23432b578d3SmrgATIMach64GP_IOGetBits 23532b578d3Smrg( 23632b578d3Smrg ATIPtr pATI 23732b578d3Smrg) 23832b578d3Smrg{ 23932b578d3Smrg return inr(GP_IO); 24032b578d3Smrg} 24132b578d3Smrg 24232b578d3Smrg#define GPIO1_MASK \ 24332b578d3Smrg (DAC_GIO_STATE_1 | DAC_GIO_DIR_1) 24432b578d3Smrg#define GPIO2_MASK \ 24532b578d3Smrg (GEN_GIO2_DATA_OUT | GEN_GIO2_DATA_IN | GEN_GIO2_WRITE) 24632b578d3Smrg 24732b578d3Smrg/* 24832b578d3Smrg * ATIMach64DAC_GENSetBits -- 24932b578d3Smrg * 25032b578d3Smrg * Controls SDA and SCL control lines through a Mach64's GEN_TEST_CNTL and 25132b578d3Smrg * DAC_CNTL registers. 25232b578d3Smrg */ 25332b578d3Smrgstatic void 25432b578d3SmrgATIMach64DAC_GENSetBits 25532b578d3Smrg( 25632b578d3Smrg ATII2CPtr pATII2C, 25732b578d3Smrg ATIPtr pATI, 25832b578d3Smrg CARD32 Bits 25932b578d3Smrg) 26032b578d3Smrg{ 26132b578d3Smrg CARD32 tmp; 26232b578d3Smrg 26332b578d3Smrg pATII2C->I2CCur = Bits; 26432b578d3Smrg 26532b578d3Smrg tmp = inr(DAC_CNTL) & ~GPIO1_MASK; 26632b578d3Smrg outr(DAC_CNTL, tmp | (Bits & GPIO1_MASK)); 26732b578d3Smrg tmp = inr(GEN_TEST_CNTL) & ~GPIO2_MASK; 26832b578d3Smrg outr(GEN_TEST_CNTL, tmp | (Bits & GPIO2_MASK)); 26932b578d3Smrg} 27032b578d3Smrg 27132b578d3Smrg/* 27232b578d3Smrg * ATIMach64DAC_GENGetBits -- 27332b578d3Smrg * 27432b578d3Smrg * Returns the status of I2C control lines through a Mach64's GEN_TEST_CNTL and 27532b578d3Smrg * DAC_CNTL registers. 27632b578d3Smrg */ 27732b578d3Smrgstatic CARD32 27832b578d3SmrgATIMach64DAC_GENGetBits 27932b578d3Smrg( 28032b578d3Smrg ATIPtr pATI 28132b578d3Smrg) 28232b578d3Smrg{ 28332b578d3Smrg return (inr(DAC_CNTL) & GPIO1_MASK) | (inr(GEN_TEST_CNTL) & GPIO2_MASK); 28432b578d3Smrg} 28532b578d3Smrg 28632b578d3Smrg/* 28732b578d3Smrg * ATITVAddOnProbe -- 28832b578d3Smrg * 28932b578d3Smrg * Probe for an ATI-TV add-on card at specific addresses on an I2C bus. 29032b578d3Smrg */ 29132b578d3Smrgstatic Bool 29232b578d3SmrgATITVAddOnProbe 29332b578d3Smrg( 29432b578d3Smrg ScrnInfoPtr pScreenInfo, 29532b578d3Smrg ATIPtr pATI, 29632b578d3Smrg I2CBusPtr pI2CBus 29732b578d3Smrg) 29832b578d3Smrg{ 29932b578d3Smrg I2CDevPtr pI2CDev = xnfcalloc(1, SizeOf(I2CDevRec)); 30032b578d3Smrg int Index; 30132b578d3Smrg I2CByte tmp; 30232b578d3Smrg 30332b578d3Smrg static const CARD8 ATITVAddOnAddresses[] = {0x70, 0x40, 0x78, 0x72, 0x42}; 30432b578d3Smrg 30532b578d3Smrg pI2CDev->DevName = "ATI-TV Add-on"; 30632b578d3Smrg pI2CDev->pI2CBus = pI2CBus; 30732b578d3Smrg pI2CDev->StartTimeout = pI2CBus->StartTimeout; 30832b578d3Smrg pI2CDev->BitTimeout = pI2CBus->BitTimeout; 30932b578d3Smrg pI2CDev->AcknTimeout = pI2CBus->AcknTimeout; 31032b578d3Smrg pI2CDev->ByteTimeout = pI2CBus->ByteTimeout; 31132b578d3Smrg 31232b578d3Smrg for (Index = 0; Index < NumberOf(ATITVAddOnAddresses); Index++) 31332b578d3Smrg { 31432b578d3Smrg pI2CDev->SlaveAddr = ATITVAddOnAddresses[Index]; 31532b578d3Smrg 31632b578d3Smrg if (xf86I2CFindDev(pI2CBus, pI2CDev->SlaveAddr)) 31732b578d3Smrg continue; 31832b578d3Smrg 31932b578d3Smrg tmp = 0xFFU; 32032b578d3Smrg 32132b578d3Smrg if (!(*pI2CBus->I2CWriteRead)(pI2CDev, &tmp, 1, NULL, 0) || 32232b578d3Smrg !(*pI2CBus->I2CWriteRead)(pI2CDev, NULL, 0, &tmp, 1) || 32332b578d3Smrg (tmp == 0xFFU) || ((tmp = tmp & 0x1FU) == /*ATI_TUNER_NONE*/0)) 32432b578d3Smrg continue; 32532b578d3Smrg 32632b578d3Smrg if (!xf86I2CDevInit(pI2CDev)) 32732b578d3Smrg { 32832b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 32932b578d3Smrg "Failed to register I2C device for ATI-TV add-on.\n"); 33032b578d3Smrg break; 33132b578d3Smrg } 33232b578d3Smrg 33332b578d3Smrg if (pATI->Tuner != tmp) 33432b578d3Smrg { 33532b578d3Smrg if (pATI->Tuner != ATI_TUNER_NONE) 33632b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_WARNING, 33732b578d3Smrg "Tuner type mismatch: BIOS 0x%x, ATI-TV 0x%x.\n", 33832b578d3Smrg pATI->Tuner, tmp); 33932b578d3Smrg 34032b578d3Smrg pATI->Tuner = tmp; 34132b578d3Smrg } 34232b578d3Smrg 34332b578d3Smrg xf86DrvMsg(pScreenInfo->scrnIndex, X_PROBED, 34432b578d3Smrg "%s tuner detected on ATI-TV add-on adapter at I2C bus address" 34532b578d3Smrg " 0x%2x.\n", ATITuners[pATI->Tuner].name, pI2CDev->SlaveAddr); 34632b578d3Smrg 34732b578d3Smrg return TRUE; 34832b578d3Smrg } 34932b578d3Smrg 3501b12faf6Smrg free(pI2CDev); 35132b578d3Smrg return FALSE; 35232b578d3Smrg} 35332b578d3Smrg 35432b578d3Smrg/* 35532b578d3Smrg * ATIMach64I2CPreInit -- 35632b578d3Smrg * 35732b578d3Smrg * This function potentially allocates an I2CBusRec and initialises it with 35832b578d3Smrg * ATI-specific and Mach64-specific information. 35932b578d3Smrg */ 36032b578d3Smrgvoid 36132b578d3SmrgATIMach64I2CPreInit 36232b578d3Smrg( 36332b578d3Smrg ScrnInfoPtr pScreenInfo, 36432b578d3Smrg ATIPtr pATI 36532b578d3Smrg) 36632b578d3Smrg{ 36732b578d3Smrg I2CBusPtr pI2CBus; 36832b578d3Smrg ATII2CPtr pATII2C; 36932b578d3Smrg 37032b578d3Smrg if ((pATI->Chip < ATI_CHIP_264CT) || (pATI->Chip >= ATI_CHIP_Mach64)) 37132b578d3Smrg return; 37232b578d3Smrg 37332b578d3Smrg /* Create an I2CBusRec and generically prime it */ 37432b578d3Smrg if (!(pI2CBus = ATICreateI2CBusRec(pScreenInfo->scrnIndex, pATI, "Mach64"))) 37532b578d3Smrg return; 37632b578d3Smrg 37732b578d3Smrg pATII2C = pI2CBus->DriverPrivate.ptr; 37832b578d3Smrg 37932b578d3Smrg switch (pATI->Chip) 38032b578d3Smrg { 38132b578d3Smrg case ATI_CHIP_264GTPRO: 38232b578d3Smrg case ATI_CHIP_264LTPRO: 38332b578d3Smrg case ATI_CHIP_264XL: 38432b578d3Smrg case ATI_CHIP_MOBILITY: 38532b578d3Smrg /* 38632b578d3Smrg * These have I2C-specific registers. Assume older I2C access 38732b578d3Smrg * mechanisms are inoperative. 38832b578d3Smrg */ 38932b578d3Smrg pATII2C->I2CSetBits = ATIMach64I2C_CNTLSetBits; 39032b578d3Smrg pATII2C->I2CGetBits = ATIMach64I2C_CNTLGetBits; 39132b578d3Smrg pATII2C->SCLDir = pATII2C->SDADir = 0; 39232b578d3Smrg pATII2C->SCLGet = pATII2C->SCLSet = GetByte(I2C_CNTL_SCL, 1); 39332b578d3Smrg pATII2C->SDAGet = pATII2C->SDASet = GetByte(I2C_CNTL_SDA, 1); 39432b578d3Smrg 39532b578d3Smrg out8(I2C_CNTL_1 + 2, GetByte(I2C_SEL, 2)); 39632b578d3Smrg out8(I2C_CNTL_0 + 0, 39732b578d3Smrg GetByte(I2C_CNTL_STAT | I2C_CNTL_HPTR_RST, 0)); 39832b578d3Smrg break; 39932b578d3Smrg 40032b578d3Smrg case ATI_CHIP_264VTB: 40132b578d3Smrg case ATI_CHIP_264GTB: 40232b578d3Smrg case ATI_CHIP_264VT3: 40332b578d3Smrg case ATI_CHIP_264GTDVD: 40432b578d3Smrg case ATI_CHIP_264LT: 40532b578d3Smrg case ATI_CHIP_264VT4: 40632b578d3Smrg case ATI_CHIP_264GT2C: 40732b578d3Smrg /* If an ImpacTV chip is found, use it to provide I2C access */ 40832b578d3Smrg if (ATIMach64ImpacTVProbe(pScreenInfo->scrnIndex, pATI)) 40932b578d3Smrg { 41032b578d3Smrg pATII2C->I2CSetBits = ATIMach64ImpacTVSetBits; 41132b578d3Smrg pATII2C->I2CGetBits = ATIMach64ImpacTVGetBits; 41232b578d3Smrg pATII2C->SCLDir = IT_SCL_DIR; 41332b578d3Smrg pATII2C->SCLGet = IT_SCL_GET; 41432b578d3Smrg pATII2C->SCLSet = IT_SCL_SET; 41532b578d3Smrg pATII2C->SDADir = IT_SDA_DIR; 41632b578d3Smrg pATII2C->SDAGet = IT_SDA_GET; 41732b578d3Smrg pATII2C->SDASet = IT_SDA_SET; 41832b578d3Smrg 41932b578d3Smrg ATIMach64MPPSetAddress(pATI, IT_I2C_CNTL); 42032b578d3Smrg outr(MPP_CONFIG, MPP_WRITEINC); 42132b578d3Smrg out8(MPP_DATA, 0x00U); 42232b578d3Smrg out8(MPP_DATA, 0x55U); 42332b578d3Smrg out8(MPP_DATA, 0x00U); 42432b578d3Smrg out8(MPP_DATA, 0x00U); 42532b578d3Smrg ATIMach64MPPWaitForIdle(pATI); 42632b578d3Smrg break; 42732b578d3Smrg } 42832b578d3Smrg /* Otherwise, fall through to the older case */ 42932b578d3Smrg 43032b578d3Smrg case ATI_CHIP_264VT: 43132b578d3Smrg case ATI_CHIP_264GT: 43232b578d3Smrg /* First try GIO pins 11 (clock) and 4 (data) */ 43332b578d3Smrg pATII2C->I2CSetBits = ATIMach64GP_IOSetBits; 43432b578d3Smrg pATII2C->I2CGetBits = ATIMach64GP_IOGetBits; 43532b578d3Smrg pATII2C->SCLDir = GP_IO_DIR_B; 43632b578d3Smrg pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_B; 43732b578d3Smrg pATII2C->SDADir = GP_IO_DIR_4; 43832b578d3Smrg pATII2C->SDAGet = pATII2C->SDASet = GP_IO_4; 43932b578d3Smrg 44032b578d3Smrg if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus)) 44132b578d3Smrg break; 44232b578d3Smrg 44332b578d3Smrg /* Next, try pins 10 (clock) and 12 (data) */ 44432b578d3Smrg pATII2C->SCLDir = GP_IO_DIR_A; 44532b578d3Smrg pATII2C->SCLGet = pATII2C->SCLSet = GP_IO_A; 44632b578d3Smrg pATII2C->SDADir = GP_IO_DIR_C; 44732b578d3Smrg pATII2C->SDAGet = pATII2C->SDASet = GP_IO_C; 44832b578d3Smrg 44932b578d3Smrg if (ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus)) 45032b578d3Smrg break; 45132b578d3Smrg /* Otherwise, fall back to ATI's first I2C implementation */ 45232b578d3Smrg 45332b578d3Smrg default: 45432b578d3Smrg /* 45532b578d3Smrg * First generation integrated controllers access GIO pin 1 (clock) 45632b578d3Smrg * though DAC_CNTL, and pin 2 (data) through GEN_TEST_CNTL. 45732b578d3Smrg */ 45832b578d3Smrg pATII2C->I2CSetBits = ATIMach64DAC_GENSetBits; 45932b578d3Smrg pATII2C->I2CGetBits = ATIMach64DAC_GENGetBits; 46032b578d3Smrg pATII2C->SCLDir = DAC_GIO_DIR_1; 46132b578d3Smrg pATII2C->SCLGet = pATII2C->SCLSet = DAC_GIO_STATE_1; 46232b578d3Smrg pATII2C->SDADir = GEN_GIO2_WRITE; 46332b578d3Smrg pATII2C->SDAGet = GEN_GIO2_DATA_IN; 46432b578d3Smrg pATII2C->SDASet = GEN_GIO2_DATA_OUT; 46532b578d3Smrg 46632b578d3Smrg (void)ATITVAddOnProbe(pScreenInfo, pATI, pI2CBus); 46732b578d3Smrg break; 46832b578d3Smrg } 46932b578d3Smrg} 470