nvbios: Add some valid register ranges for nv50.
[nouveau] / src / nv_i2c.c
1
2 #include "nv_include.h"
3
4 /*
5  * DDC1 support only requires DDC_SDA_MASK,
6  * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK
7  */
8 #define DDC_SDA_READ_MASK  (1 << 3)
9 #define DDC_SCL_READ_MASK  (1 << 2)
10 #define DDC_SDA_WRITE_MASK (1 << 4)
11 #define DDC_SCL_WRITE_MASK (1 << 5)
12
13 static void
14 NVI2CGetBits(I2CBusPtr b, int *clock, int *data)
15 {
16         NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
17         unsigned char val;
18
19         /* Get the result. */
20         /* Doing this on head 0 seems fine. */
21         val = NVReadVgaCrtc(pNv, 0, b->DriverPrivate.uval);
22
23         *clock = (val & DDC_SCL_READ_MASK) != 0;
24         *data  = (val & DDC_SDA_READ_MASK) != 0;
25 }
26
27 static void
28 NVI2CPutBits(I2CBusPtr b, int clock, int data)
29 {
30         NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
31         unsigned char val;
32
33         /* Doing this on head 0 seems fine. */
34         val = NVReadVgaCrtc(pNv, 0, b->DriverPrivate.uval + 1) & 0xf0;
35         if (clock)
36                 val |= DDC_SCL_WRITE_MASK;
37         else
38                 val &= ~DDC_SCL_WRITE_MASK;
39
40         if (data)
41                 val |= DDC_SDA_WRITE_MASK;
42         else
43                 val &= ~DDC_SDA_WRITE_MASK;
44
45         /* Doing this on head 0 seems fine. */
46         NVWriteVgaCrtc(pNv, 0, b->DriverPrivate.uval + 1, val | 0x1);
47 }
48
49 static void NV50_I2CPutBits(I2CBusPtr b, int clock, int data)
50 {
51         NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
52
53         NVWrite(pNv, NV50_I2C_PORT(b->DriverPrivate.val), (4 | clock | data << 1));
54 }
55
56 static void NV50_I2CGetBits(I2CBusPtr b, int *clock, int *data)
57 {
58         NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]);
59         unsigned char val;
60
61         val = NVRead(pNv, NV50_I2C_PORT(b->DriverPrivate.val));
62         *clock = !!(val & 1);
63         *data = !!(val & 2);
64 }
65
66 Bool
67 NV_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name)
68 {
69         I2CBusPtr pI2CBus;
70         NVPtr pNv = NVPTR(pScrn);
71
72         pI2CBus = xf86CreateI2CBusRec();
73         if(!pI2CBus)
74                 return FALSE;
75
76         pI2CBus->BusName    = name;
77         pI2CBus->scrnIndex  = pScrn->scrnIndex;
78         if (pNv->Architecture == NV_ARCH_50) {
79                 pI2CBus->I2CPutBits = NV50_I2CPutBits;
80                 pI2CBus->I2CGetBits = NV50_I2CGetBits;
81                 /* Could this be used for the rest as well? */
82                 pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
83                 pI2CBus->StartTimeout = 550;
84                 pI2CBus->BitTimeout = 40;
85                 pI2CBus->ByteTimeout = 40;
86                 pI2CBus->AcknTimeout = 40;
87         } else {
88                 pI2CBus->I2CPutBits = NVI2CPutBits;
89                 pI2CBus->I2CGetBits = NVI2CGetBits;
90                 pI2CBus->AcknTimeout = 5;
91         }
92
93         pI2CBus->DriverPrivate.uval = i2c_reg;
94
95         if (!xf86I2CBusInit(pI2CBus)) {
96                 return FALSE;
97         }
98
99         *bus_ptr = pI2CBus;
100         return TRUE;
101 }
102