diff options
-rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 42 | ||||
-rw-r--r-- | include/linux/i2c-algo-bit.h | 6 |
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 fc16f9d268a..d9d0ec49e60 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 */ | |||
57 | static inline void sdalo(struct i2c_algo_bit_data *adap) | 57 | static 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 | ||
63 | static inline void sdahi(struct i2c_algo_bit_data *adap) | 63 | static 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 | ||
69 | static inline void scllo(struct i2c_algo_bit_data *adap) | 69 | static 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 | ||
118 | static void i2c_repstart(struct i2c_algo_bit_data *adap) | 119 | static 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 d91dab88635..9ee0f800592 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 | ||