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