summaryrefslogtreecommitdiff
path: root/src/i830_i2c.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@ukulele.keithp.com>2006-12-19 01:32:54 -0800
committerKeith Packard <keithp@ukulele.keithp.com>2006-12-19 01:32:54 -0800
commit7b8056e3e347b15b37be0116315d7d3a23aef99f (patch)
treee7c5adb5a661c7ae3a13e50356a9dca25ceca66b /src/i830_i2c.c
parenteedef7adc53dd8337d27c02551c5778fb43bae05 (diff)
Writing 1 to I2C line means to tristate the bus so others can manipulate it.
We were forcing bus lines to 1 which was breaking DDC for some monitors. Instead, make the PutBits function just tristate when writing 1 bits.
Diffstat (limited to 'src/i830_i2c.c')
-rw-r--r--src/i830_i2c.c51
1 files changed, 22 insertions, 29 deletions
diff --git a/src/i830_i2c.c b/src/i830_i2c.c
index d246c167..8fd12ea9 100644
--- a/src/i830_i2c.c
+++ b/src/i830_i2c.c
@@ -272,31 +272,21 @@ i830I2CGetBits(I2CBusPtr b, int *clock, int *data)
{
ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex];
I830Ptr pI830 = I830PTR(pScrn);
- CARD32 val, tristate = 0;
+ CARD32 val;
val = INREG(b->DriverPrivate.uval);
- /* If we've released either of the lines from holding low, tristate them
- * so that we can successfully read. Some hardware fails to read low
- * values driven by slaves when our master is not tri-stated, while other
- * chips succeed.
+ /*
+ * to read valid data, we must have written a 1 to
+ * the associated bit. Writing a 1 is done by
+ * tri-stating the bus in PutBits, so we needn't make
+ * sure that is true here
*/
- if ((val & GPIO_DATA_DIR_OUT) && (val & GPIO_DATA_VAL_OUT))
- tristate |= GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK;
- if ((val & GPIO_CLOCK_DIR_OUT) && (val & GPIO_CLOCK_VAL_OUT))
- tristate |= GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK;
-
- if (tristate) {
- OUTREG(b->DriverPrivate.uval, tristate);
-
- val = INREG(b->DriverPrivate.uval);
- }
-
*data = (val & GPIO_DATA_VAL_IN) != 0;
*clock = (val & GPIO_CLOCK_VAL_IN) != 0;
#if I2C_DEBUG
- ErrorF("Getting I2C: %c %c\n",
+ ErrorF("Getting %s: %c %c\n", b->BusName,
*clock ? '^' : 'v',
*data ? '^' : 'v');
#endif
@@ -306,6 +296,7 @@ static void
i830I2CPutBits(I2CBusPtr b, int clock, int data)
{
CARD32 reserved = 0;
+ CARD32 data_bits, clock_bits;
#if I2C_DEBUG
int cur_clock, cur_data;
@@ -318,11 +309,11 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data)
i830I2CGetBits(b, &cur_clock, &cur_data);
if (first) {
- ErrorF("I2C Debug: C D C D\n");
+ ErrorF("%s Debug: C D C D\n", b->BusName);
first = FALSE;
}
- ErrorF("Setting I2C 0x%08x to: %c %c\n",
+ ErrorF("Setting %s 0x%08x to: %c %c\n", b->BusName,
(int)b->DriverPrivate.uval,
clock ? '^' : 'v',
data ? '^' : 'v');
@@ -334,17 +325,19 @@ i830I2CPutBits(I2CBusPtr b, int clock, int data)
(GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE);
}
- OUTREG(b->DriverPrivate.uval,
- reserved |
- (data ? GPIO_DATA_VAL_OUT : 0) |
- (clock ? GPIO_CLOCK_VAL_OUT : 0) |
- GPIO_CLOCK_DIR_OUT |
- GPIO_DATA_DIR_OUT |
- GPIO_CLOCK_DIR_MASK |
- GPIO_CLOCK_VAL_MASK |
- GPIO_DATA_DIR_MASK |
- GPIO_DATA_VAL_MASK);
+ /* data or clock == 1 means to tristate the bus. otherwise, drive it low */
+ if (data)
+ data_bits = GPIO_DATA_DIR_IN|GPIO_DATA_DIR_MASK;
+ else
+ data_bits = GPIO_DATA_DIR_OUT|GPIO_DATA_DIR_MASK|GPIO_DATA_VAL_MASK;
+ if (clock)
+ clock_bits = GPIO_CLOCK_DIR_IN|GPIO_CLOCK_DIR_MASK;
+ else
+ clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK;
+
+ OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits);
}
+
#endif
/* the i830 has a number of I2C Buses */