diff options
Diffstat (limited to 'drivers/i2c/algos/i2c-algo-pcf.c')
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pcf.c | 85 |
1 files changed, 13 insertions, 72 deletions
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index ab2e6f3498b4..8907b0191677 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c | |||
@@ -203,35 +203,6 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
203 | /* ----- Utility functions | 203 | /* ----- Utility functions |
204 | */ | 204 | */ |
205 | 205 | ||
206 | static inline int try_address(struct i2c_algo_pcf_data *adap, | ||
207 | unsigned char addr, int retries) | ||
208 | { | ||
209 | int i, status, ret = -1; | ||
210 | int wfp; | ||
211 | for (i=0;i<retries;i++) { | ||
212 | i2c_outb(adap, addr); | ||
213 | i2c_start(adap); | ||
214 | status = get_pcf(adap, 1); | ||
215 | if ((wfp = wait_for_pin(adap, &status)) >= 0) { | ||
216 | if ((status & I2C_PCF_LRB) == 0) { | ||
217 | i2c_stop(adap); | ||
218 | break; /* success! */ | ||
219 | } | ||
220 | } | ||
221 | if (wfp == -EINTR) { | ||
222 | /* arbitration lost */ | ||
223 | udelay(adap->udelay); | ||
224 | return -EINTR; | ||
225 | } | ||
226 | i2c_stop(adap); | ||
227 | udelay(adap->udelay); | ||
228 | } | ||
229 | DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i, | ||
230 | addr)); | ||
231 | return ret; | ||
232 | } | ||
233 | |||
234 | |||
235 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, | 206 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, |
236 | int count, int last) | 207 | int count, int last) |
237 | { | 208 | { |
@@ -321,47 +292,19 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, | |||
321 | } | 292 | } |
322 | 293 | ||
323 | 294 | ||
324 | static inline int pcf_doAddress(struct i2c_algo_pcf_data *adap, | 295 | static int pcf_doAddress(struct i2c_algo_pcf_data *adap, |
325 | struct i2c_msg *msg, int retries) | 296 | struct i2c_msg *msg) |
326 | { | 297 | { |
327 | unsigned short flags = msg->flags; | 298 | unsigned short flags = msg->flags; |
328 | unsigned char addr; | 299 | unsigned char addr; |
329 | int ret; | 300 | |
330 | if ( (flags & I2C_M_TEN) ) { | 301 | addr = msg->addr << 1; |
331 | /* a ten bit address */ | 302 | if (flags & I2C_M_RD) |
332 | addr = 0xf0 | (( msg->addr >> 7) & 0x03); | 303 | addr |= 1; |
333 | DEB2(printk(KERN_DEBUG "addr0: %d\n",addr)); | 304 | if (flags & I2C_M_REV_DIR_ADDR) |
334 | /* try extended address code...*/ | 305 | addr ^= 1; |
335 | ret = try_address(adap, addr, retries); | 306 | i2c_outb(adap, addr); |
336 | if (ret!=1) { | 307 | |
337 | printk(KERN_ERR "died at extended address code.\n"); | ||
338 | return -EREMOTEIO; | ||
339 | } | ||
340 | /* the remaining 8 bit address */ | ||
341 | i2c_outb(adap,msg->addr & 0x7f); | ||
342 | /* Status check comes here */ | ||
343 | if (ret != 1) { | ||
344 | printk(KERN_ERR "died at 2nd address code.\n"); | ||
345 | return -EREMOTEIO; | ||
346 | } | ||
347 | if ( flags & I2C_M_RD ) { | ||
348 | i2c_repstart(adap); | ||
349 | /* okay, now switch into reading mode */ | ||
350 | addr |= 0x01; | ||
351 | ret = try_address(adap, addr, retries); | ||
352 | if (ret!=1) { | ||
353 | printk(KERN_ERR "died at extended address code.\n"); | ||
354 | return -EREMOTEIO; | ||
355 | } | ||
356 | } | ||
357 | } else { /* normal 7bit address */ | ||
358 | addr = ( msg->addr << 1 ); | ||
359 | if (flags & I2C_M_RD ) | ||
360 | addr |= 1; | ||
361 | if (flags & I2C_M_REV_DIR_ADDR ) | ||
362 | addr ^= 1; | ||
363 | i2c_outb(adap, addr); | ||
364 | } | ||
365 | return 0; | 308 | return 0; |
366 | } | 309 | } |
367 | 310 | ||
@@ -390,7 +333,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
390 | pmsg->flags & I2C_M_RD ? "read" : "write", | 333 | pmsg->flags & I2C_M_RD ? "read" : "write", |
391 | pmsg->len, pmsg->addr, i + 1, num);) | 334 | pmsg->len, pmsg->addr, i + 1, num);) |
392 | 335 | ||
393 | ret = pcf_doAddress(adap, pmsg, i2c_adap->retries); | 336 | ret = pcf_doAddress(adap, pmsg); |
394 | 337 | ||
395 | /* Send START */ | 338 | /* Send START */ |
396 | if (i == 0) { | 339 | if (i == 0) { |
@@ -453,7 +396,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
453 | static u32 pcf_func(struct i2c_adapter *adap) | 396 | static u32 pcf_func(struct i2c_adapter *adap) |
454 | { | 397 | { |
455 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | 398 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
456 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; | 399 | I2C_FUNC_PROTOCOL_MANGLING; |
457 | } | 400 | } |
458 | 401 | ||
459 | /* -----exported algorithm data: ------------------------------------- */ | 402 | /* -----exported algorithm data: ------------------------------------- */ |
@@ -475,9 +418,7 @@ int i2c_pcf_add_bus(struct i2c_adapter *adap) | |||
475 | 418 | ||
476 | /* register new adapter to i2c module... */ | 419 | /* register new adapter to i2c module... */ |
477 | adap->algo = &pcf_algo; | 420 | adap->algo = &pcf_algo; |
478 | 421 | adap->timeout = 100; | |
479 | adap->timeout = 100; /* default values, should */ | ||
480 | adap->retries = 3; /* be replaced by defines */ | ||
481 | 422 | ||
482 | if ((rval = pcf_init_8584(pcf_adap))) | 423 | if ((rval = pcf_init_8584(pcf_adap))) |
483 | return rval; | 424 | return rval; |