aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2007-05-01 17:26:33 -0400
committerJean Delvare <khali@hyperion.delvare>2007-05-01 17:26:33 -0400
commit424ed67c7dae37e8115e1bebc3261e86a624dff2 (patch)
tree5873a171f3a54109ac680de55bf5dbf139b67a23
parent7c175499822ba34ba60f32e4995fcc16c007d308 (diff)
i2c-algo-bit: Implement a 50/50 SCL duty cycle
The original i2c-algo-bit implementation uses a 33/66 SCL duty cycle when bits are being written on the bus. While the I2C specification doesn't forbid it, this prevents us from driving the I2C bus to its max speed, limiting us to 66 kbps max on standard I2C busses. Implementing a 50/50 duty cycle instead lets us max out the bandwidth up to the theoretical max of 100 kbps on standard I2C busses. This is particularly important when large amounts of data need to be transfered over the bus, as is the case with some TV adapters when the firmware is being uploaded. In fact this change even allows, at least in theory, fast-mode I2C support at 125, 166 and 250 kbps. There's no way to reach the theoretical max of 400 kbps with this implementation. But I don't think we want to put efforts in that direction anyway: software-driven I2C is very CPU-intensive and bad for latency. Other timing changes: * Don't set SDA high explicitly on error, we're going to issue a stop condition before we leave anyway. * If an error occurs when sending the slave address, yield the CPU before retrying, and remove the additional delay after the new start condition. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/i2c/algos/i2c-algo-bit.c42
-rw-r--r--include/linux/i2c-algo-bit.h6
2 files changed, 26 insertions, 22 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c
index fc16f9d268a3..d9d0ec49e60d 100644
--- a/drivers/i2c/algos/i2c-algo-bit.c
+++ b/drivers/i2c/algos/i2c-algo-bit.c
@@ -57,19 +57,19 @@ static int bit_test; /* see if the line-setting functions work */
57static inline void sdalo(struct i2c_algo_bit_data *adap) 57static inline void sdalo(struct i2c_algo_bit_data *adap)
58{ 58{
59 setsda(adap,0); 59 setsda(adap,0);
60 udelay(adap->udelay); 60 udelay((adap->udelay + 1) / 2);
61} 61}
62 62
63static inline void sdahi(struct i2c_algo_bit_data *adap) 63static inline void sdahi(struct i2c_algo_bit_data *adap)
64{ 64{
65 setsda(adap,1); 65 setsda(adap,1);
66 udelay(adap->udelay); 66 udelay((adap->udelay + 1) / 2);
67} 67}
68 68
69static inline void scllo(struct i2c_algo_bit_data *adap) 69static inline void scllo(struct i2c_algo_bit_data *adap)
70{ 70{
71 setscl(adap,0); 71 setscl(adap,0);
72 udelay(adap->udelay); 72 udelay(adap->udelay / 2);
73} 73}
74 74
75/* 75/*
@@ -111,18 +111,19 @@ static void i2c_start(struct i2c_algo_bit_data *adap)
111{ 111{
112 /* assert: scl, sda are high */ 112 /* assert: scl, sda are high */
113 DEBPROTO(printk("S ")); 113 DEBPROTO(printk("S "));
114 sdalo(adap); 114 setsda(adap, 0);
115 udelay(adap->udelay);
115 scllo(adap); 116 scllo(adap);
116} 117}
117 118
118static void i2c_repstart(struct i2c_algo_bit_data *adap) 119static void i2c_repstart(struct i2c_algo_bit_data *adap)
119{ 120{
120 /* scl, sda may not be high */ 121 /* assert: scl is low */
121 DEBPROTO(printk(" Sr ")); 122 DEBPROTO(printk(" Sr "));
122 setsda(adap,1); 123 sdahi(adap);
123 sclhi(adap); 124 sclhi(adap);
124 125 setsda(adap, 0);
125 sdalo(adap); 126 udelay(adap->udelay);
126 scllo(adap); 127 scllo(adap);
127} 128}
128 129
@@ -133,7 +134,8 @@ static void i2c_stop(struct i2c_algo_bit_data *adap)
133 /* assert: scl is low */ 134 /* assert: scl is low */
134 sdalo(adap); 135 sdalo(adap);
135 sclhi(adap); 136 sclhi(adap);
136 sdahi(adap); 137 setsda(adap, 1);
138 udelay(adap->udelay);
137} 139}
138 140
139 141
@@ -156,18 +158,16 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
156 for ( i=7 ; i>=0 ; i-- ) { 158 for ( i=7 ; i>=0 ; i-- ) {
157 sb = c & ( 1 << i ); 159 sb = c & ( 1 << i );
158 setsda(adap,sb); 160 setsda(adap,sb);
159 udelay(adap->udelay); 161 udelay((adap->udelay + 1) / 2);
160 DEBPROTO(printk(KERN_DEBUG "%d",sb!=0)); 162 DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
161 if (sclhi(adap)<0) { /* timed out */ 163 if (sclhi(adap)<0) { /* timed out */
162 sdahi(adap); /* we don't want to block the net */
163 DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i)); 164 DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i));
164 return -ETIMEDOUT; 165 return -ETIMEDOUT;
165 }; 166 };
166 /* do arbitration here: 167 /* do arbitration here:
167 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here. 168 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
168 */ 169 */
169 setscl(adap, 0 ); 170 scllo(adap);
170 udelay(adap->udelay);
171 } 171 }
172 sdahi(adap); 172 sdahi(adap);
173 if (sclhi(adap)<0){ /* timeout */ 173 if (sclhi(adap)<0){ /* timeout */
@@ -204,7 +204,8 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)
204 indata *= 2; 204 indata *= 2;
205 if ( getsda(adap) ) 205 if ( getsda(adap) )
206 indata |= 0x01; 206 indata |= 0x01;
207 scllo(adap); 207 setscl(adap, 0);
208 udelay(i == 7 ? adap->udelay / 2 : adap->udelay);
208 } 209 }
209 /* assert: scl is low */ 210 /* assert: scl is low */
210 DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff)); 211 DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff));
@@ -315,9 +316,9 @@ static int try_address(struct i2c_adapter *i2c_adap,
315 if (ret == 1 || i == retries) 316 if (ret == 1 || i == retries)
316 break; 317 break;
317 i2c_stop(adap); 318 i2c_stop(adap);
318 udelay(5/*adap->udelay*/);
319 i2c_start(adap);
320 udelay(adap->udelay); 319 udelay(adap->udelay);
320 yield();
321 i2c_start(adap);
321 } 322 }
322 DEB2(if (i) 323 DEB2(if (i)
323 printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n", 324 printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n",
@@ -377,20 +378,21 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
377 if (msg->flags & I2C_M_NO_RD_ACK) 378 if (msg->flags & I2C_M_NO_RD_ACK)
378 continue; 379 continue;
379 380
381 /* assert: sda is high */
380 if ( count > 0 ) { /* send ack */ 382 if ( count > 0 ) { /* send ack */
381 sdalo(adap); 383 setsda(adap, 0);
384 udelay((adap->udelay + 1) / 2);
382 DEBPROTO(printk(" Am ")); 385 DEBPROTO(printk(" Am "));
383 } else { 386 } else {
384 sdahi(adap); /* neg. ack on last byte */ 387 /* neg. ack on last byte */
388 udelay((adap->udelay + 1) / 2);
385 DEBPROTO(printk(" NAm ")); 389 DEBPROTO(printk(" NAm "));
386 } 390 }
387 if (sclhi(adap)<0) { /* timeout */ 391 if (sclhi(adap)<0) { /* timeout */
388 sdahi(adap);
389 printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n"); 392 printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
390 return -ETIMEDOUT; 393 return -ETIMEDOUT;
391 }; 394 };
392 scllo(adap); 395 scllo(adap);
393 sdahi(adap);
394 396
395 /* Some SMBus transactions require that we receive the 397 /* Some SMBus transactions require that we receive the
396 transaction length as the first read byte. */ 398 transaction length as the first read byte. */
diff --git a/include/linux/i2c-algo-bit.h b/include/linux/i2c-algo-bit.h
index d91dab886357..9ee0f800592f 100644
--- a/include/linux/i2c-algo-bit.h
+++ b/include/linux/i2c-algo-bit.h
@@ -38,8 +38,10 @@ struct i2c_algo_bit_data {
38 int (*getscl) (void *data); 38 int (*getscl) (void *data);
39 39
40 /* local settings */ 40 /* local settings */
41 int udelay; /* half-clock-cycle time in microsecs */ 41 int udelay; /* half clock cycle time in us,
42 /* i.e. clock is (500 / udelay) KHz */ 42 minimum 2 us for fast-mode I2C,
43 minimum 5 us for standard-mode I2C and SMBus,
44 maximum 50 us for SMBus */
43 int timeout; /* in jiffies */ 45 int timeout; /* in jiffies */
44}; 46};
45 47