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