alp_i2c.c revision 76888252
1/* (c) Itai Nahshon */
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_i2c.c,v 1.6 1999/02/28 11:19:38 dawes Exp $ */
8
9#include "xf86.h"
10#include "xf86_OSproc.h"
11#include "compiler.h"
12
13#include "xf86Pci.h"
14#include "xf86PciInfo.h"
15
16#include "vgaHW.h"
17
18#include "cir.h"
19#define _ALP_PRIVATE_
20#include "alp.h"
21
22/*
23 * Switch between internal I2C bus and external (DDC) bus.
24 * There is one I2C port controlled bu SR08 and the programmable
25 * outputs control a multiplexer.
26 */
27static Bool
28AlpI2CSwitchToBus(I2CBusPtr b)
29{
30	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
31	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
32	CARD8 reg = hwp->readGr(hwp, 0x17);
33	if (b == pCir->I2CPtr1) {
34	    if ((reg & 0x60) == 0)
35  		return TRUE;
36	    reg &= ~0x60;
37	}
38	else if(b == pCir->I2CPtr2) {
39	    if ((reg & 0x60) != 0)
40  		return TRUE;
41	    reg |= 0x60;
42	} else 	return FALSE;
43
44	/* ErrorF("AlpI2CSwitchToBus: \"%s\"\n", b->BusName); */
45	hwp->writeGr(hwp, 0x17, reg);
46	return TRUE;
47}
48
49static void
50AlpI2CPutBits(I2CBusPtr b, int clock,  int data)
51{
52	unsigned int reg = 0xfc;
53	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
54	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
55
56	if (!AlpI2CSwitchToBus(b))
57		return;
58
59	if (clock) reg |= 1;
60	if (data)  reg |= 2;
61	hwp->writeSeq(hwp, 0x08, reg);
62	/* ErrorF("AlpI2CPutBits: %d %d\n", clock, data); */
63}
64
65static void
66AlpI2CGetBits(I2CBusPtr b, int *clock, int *data)
67{
68	unsigned int reg;
69	CirPtr pCir = ((CirPtr)b->DriverPrivate.ptr);
70	vgaHWPtr hwp = VGAHWPTR(pCir->pScrn);
71
72	if (!AlpI2CSwitchToBus(b))
73		return;
74
75	reg = hwp->readSeq(hwp, 0x08);
76	*clock = (reg & 0x04) != 0;
77	*data  = (reg & 0x80) != 0;
78	/* ErrorF("AlpI2CGetBits: %d %d\n", *clock, *data); */
79}
80
81Bool
82AlpI2CInit(ScrnInfoPtr pScrn)
83{
84	CirPtr pCir = CIRPTR(pScrn);
85	I2CBusPtr I2CPtr;
86
87#ifdef ALP_DEBUG
88	ErrorF("AlpI2CInit\n");
89#endif
90
91	switch(pCir->Chipset) {
92	case PCI_CHIP_GD5446:
93	case PCI_CHIP_GD5480:
94		break;
95	default:
96		return FALSE;
97	}
98
99
100	I2CPtr = xf86CreateI2CBusRec();
101	if (!I2CPtr) return FALSE;
102
103	pCir->I2CPtr1 = I2CPtr;
104
105	I2CPtr->BusName    = "I2C bus 1";
106	I2CPtr->scrnIndex  = pScrn->scrnIndex;
107	I2CPtr->I2CPutBits = AlpI2CPutBits;
108	I2CPtr->I2CGetBits = AlpI2CGetBits;
109	I2CPtr->DriverPrivate.ptr = pCir;
110
111	if (!xf86I2CBusInit(I2CPtr))
112		return FALSE;
113
114	I2CPtr = xf86CreateI2CBusRec();
115	if (!I2CPtr) return FALSE;
116
117	pCir->I2CPtr2 = I2CPtr;
118
119	I2CPtr->BusName    = "I2C bus 2";
120	I2CPtr->scrnIndex  = pScrn->scrnIndex;
121	I2CPtr->I2CPutBits = AlpI2CPutBits;
122	I2CPtr->I2CGetBits = AlpI2CGetBits;
123	I2CPtr->DriverPrivate.ptr = pCir;
124
125	if (!xf86I2CBusInit(I2CPtr))
126		return FALSE;
127
128	return TRUE;
129}
130