176888252Smrg/* (c) Itai Nahshon */ 276888252Smrg 376888252Smrg#ifdef HAVE_CONFIG_H 476888252Smrg#include "config.h" 576888252Smrg#endif 676888252Smrg 776888252Smrg#include "xf86.h" 876888252Smrg#include "xf86_OSproc.h" 976888252Smrg#include "compiler.h" 1076888252Smrg 1176888252Smrg#include "xf86Pci.h" 1276888252Smrg 1376888252Smrg#include "vgaHW.h" 1476888252Smrg 1576888252Smrg#include "cir.h" 1676888252Smrg#define _ALP_PRIVATE_ 1776888252Smrg#include "alp.h" 1876888252Smrg 190814a2baSmrg 200814a2baSmrgstatic char strI2CBus1[] = "I2C bus 1"; 210814a2baSmrgstatic char strI2CBus2[] = "I2C bus 2"; 220814a2baSmrg 230814a2baSmrg 2476888252Smrg/* 2576888252Smrg * Switch between internal I2C bus and external (DDC) bus. 2676888252Smrg * There is one I2C port controlled bu SR08 and the programmable 2776888252Smrg * outputs control a multiplexer. 2876888252Smrg */ 2976888252Smrgstatic Bool 3076888252SmrgAlpI2CSwitchToBus(I2CBusPtr b) 3176888252Smrg{ 3276888252Smrg CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr); 3376888252Smrg vgaHWPtr hwp = VGAHWPTR(pCir->pScrn); 3476888252Smrg CARD8 reg = hwp->readGr(hwp, 0x17); 3576888252Smrg if (b == pCir->I2CPtr1) { 3676888252Smrg if ((reg & 0x60) == 0) 3776888252Smrg return TRUE; 3876888252Smrg reg &= ~0x60; 3976888252Smrg } 4076888252Smrg else if(b == pCir->I2CPtr2) { 4176888252Smrg if ((reg & 0x60) != 0) 4276888252Smrg return TRUE; 4376888252Smrg reg |= 0x60; 4476888252Smrg } else return FALSE; 4576888252Smrg 4676888252Smrg /* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */ 4776888252Smrg hwp->writeGr(hwp, 0x17, reg); 4876888252Smrg return TRUE; 4976888252Smrg} 5076888252Smrg 5176888252Smrgstatic void 5276888252SmrgAlpI2CPutBits(I2CBusPtr b, int clock, int data) 5376888252Smrg{ 5476888252Smrg unsigned int reg = 0xfc; 5576888252Smrg CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr); 5676888252Smrg vgaHWPtr hwp = VGAHWPTR(pCir->pScrn); 5776888252Smrg 5876888252Smrg if (!AlpI2CSwitchToBus(b)) 5976888252Smrg return; 6076888252Smrg 6176888252Smrg if (clock) reg |= 1; 6276888252Smrg if (data) reg |= 2; 6376888252Smrg hwp->writeSeq(hwp, 0x08, reg); 6476888252Smrg /* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */ 6576888252Smrg} 6676888252Smrg 6776888252Smrgstatic void 6876888252SmrgAlpI2CGetBits(I2CBusPtr b, int *clock, int *data) 6976888252Smrg{ 7076888252Smrg unsigned int reg; 7176888252Smrg CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr); 7276888252Smrg vgaHWPtr hwp = VGAHWPTR(pCir->pScrn); 7376888252Smrg 7476888252Smrg if (!AlpI2CSwitchToBus(b)) 7576888252Smrg return; 7676888252Smrg 7776888252Smrg reg = hwp->readSeq(hwp, 0x08); 7876888252Smrg *clock = (reg & 0x04) != 0; 7976888252Smrg *data = (reg & 0x80) != 0; 8076888252Smrg /* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */ 8176888252Smrg} 8276888252Smrg 8376888252SmrgBool 8476888252SmrgAlpI2CInit(ScrnInfoPtr pScrn) 8576888252Smrg{ 8676888252Smrg CirPtr pCir = CIRPTR(pScrn); 8776888252Smrg I2CBusPtr I2CPtr; 8876888252Smrg 8976888252Smrg#ifdef ALP_DEBUG 9076888252Smrg ErrorF("AlpI2CInit\n"); 9176888252Smrg#endif 9276888252Smrg 9376888252Smrg switch(pCir->Chipset) { 9476888252Smrg case PCI_CHIP_GD5446: 9576888252Smrg case PCI_CHIP_GD5480: 9676888252Smrg break; 9776888252Smrg default: 9876888252Smrg return FALSE; 9976888252Smrg } 10076888252Smrg 10176888252Smrg 10276888252Smrg I2CPtr = xf86CreateI2CBusRec(); 10376888252Smrg if (!I2CPtr) return FALSE; 10476888252Smrg 10576888252Smrg pCir->I2CPtr1 = I2CPtr; 10676888252Smrg 1070814a2baSmrg I2CPtr->BusName = strI2CBus1; 10876888252Smrg I2CPtr->scrnIndex = pScrn->scrnIndex; 10976888252Smrg I2CPtr->I2CPutBits = AlpI2CPutBits; 11076888252Smrg I2CPtr->I2CGetBits = AlpI2CGetBits; 11176888252Smrg I2CPtr->DriverPrivate.ptr = pCir; 11276888252Smrg 11376888252Smrg if (!xf86I2CBusInit(I2CPtr)) 11476888252Smrg return FALSE; 11576888252Smrg 11676888252Smrg I2CPtr = xf86CreateI2CBusRec(); 11776888252Smrg if (!I2CPtr) return FALSE; 11876888252Smrg 11976888252Smrg pCir->I2CPtr2 = I2CPtr; 12076888252Smrg 1210814a2baSmrg I2CPtr->BusName = strI2CBus2; 12276888252Smrg I2CPtr->scrnIndex = pScrn->scrnIndex; 12376888252Smrg I2CPtr->I2CPutBits = AlpI2CPutBits; 12476888252Smrg I2CPtr->I2CGetBits = AlpI2CGetBits; 12576888252Smrg I2CPtr->DriverPrivate.ptr = pCir; 12676888252Smrg 12776888252Smrg if (!xf86I2CBusInit(I2CPtr)) 12876888252Smrg return FALSE; 12976888252Smrg 13076888252Smrg return TRUE; 13176888252Smrg} 132