diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/i2c/algos | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/i2c/algos')
-rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 42 | ||||
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pca.c | 42 | ||||
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pcf.c | 3 | ||||
-rw-r--r-- | drivers/i2c/algos/i2c-algo-pcf.h | 3 |
4 files changed, 37 insertions, 53 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index fad22b0bb5b..eca3bcc4599 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -15,8 +15,7 @@ | |||
15 | 15 | ||
16 | You should have received a copy of the GNU General Public License | 16 | You should have received a copy of the GNU General Public License |
17 | along with this program; if not, write to the Free Software | 17 | along with this program; if not, write to the Free Software |
18 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | MA 02110-1301 USA. | ||
20 | * ------------------------------------------------------------------------- */ | 19 | * ------------------------------------------------------------------------- */ |
21 | 20 | ||
22 | /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki | 21 | /* With some changes from Frodo Looijaard <frodol@dds.nl>, Kyösti Mälkki |
@@ -48,8 +47,8 @@ | |||
48 | /* ----- global variables --------------------------------------------- */ | 47 | /* ----- global variables --------------------------------------------- */ |
49 | 48 | ||
50 | static int bit_test; /* see if the line-setting functions work */ | 49 | static int bit_test; /* see if the line-setting functions work */ |
51 | module_param(bit_test, int, S_IRUGO); | 50 | module_param(bit_test, bool, 0); |
52 | MODULE_PARM_DESC(bit_test, "lines testing - 0 off; 1 report; 2 fail if stuck"); | 51 | MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck"); |
53 | 52 | ||
54 | #ifdef DEBUG | 53 | #ifdef DEBUG |
55 | static int i2c_debug = 1; | 54 | static int i2c_debug = 1; |
@@ -104,15 +103,9 @@ static int sclhi(struct i2c_algo_bit_data *adap) | |||
104 | * chips may hold it low ("clock stretching") while they | 103 | * chips may hold it low ("clock stretching") while they |
105 | * are processing data internally. | 104 | * are processing data internally. |
106 | */ | 105 | */ |
107 | if (time_after(jiffies, start + adap->timeout)) { | 106 | if (time_after(jiffies, start + adap->timeout)) |
108 | /* Test one last time, as we may have been preempted | ||
109 | * between last check and timeout test. | ||
110 | */ | ||
111 | if (getscl(adap)) | ||
112 | break; | ||
113 | return -ETIMEDOUT; | 107 | return -ETIMEDOUT; |
114 | } | 108 | cond_resched(); |
115 | cpu_relax(); | ||
116 | } | 109 | } |
117 | #ifdef DEBUG | 110 | #ifdef DEBUG |
118 | if (jiffies != start && i2c_debug >= 3) | 111 | if (jiffies != start && i2c_debug >= 3) |
@@ -257,9 +250,7 @@ static int test_bus(struct i2c_adapter *i2c_adap) | |||
257 | sda = getsda(adap); | 250 | sda = getsda(adap); |
258 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); | 251 | scl = (adap->getscl == NULL) ? 1 : getscl(adap); |
259 | if (!scl || !sda) { | 252 | if (!scl || !sda) { |
260 | printk(KERN_WARNING | 253 | printk(KERN_WARNING "%s: bus seems to be busy\n", name); |
261 | "%s: bus seems to be busy (scl=%d, sda=%d)\n", | ||
262 | name, scl, sda); | ||
263 | goto bailout; | 254 | goto bailout; |
264 | } | 255 | } |
265 | 256 | ||
@@ -450,7 +441,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
450 | acknak(i2c_adap, 0); | 441 | acknak(i2c_adap, 0); |
451 | dev_err(&i2c_adap->dev, "readbytes: invalid " | 442 | dev_err(&i2c_adap->dev, "readbytes: invalid " |
452 | "block length (%d)\n", inval); | 443 | "block length (%d)\n", inval); |
453 | return -EPROTO; | 444 | return -EREMOTEIO; |
454 | } | 445 | } |
455 | /* The original count value accounts for the extra | 446 | /* The original count value accounts for the extra |
456 | bytes, that is, either 1 for a regular transaction, | 447 | bytes, that is, either 1 for a regular transaction, |
@@ -479,7 +470,7 @@ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
479 | * reads, writes as well as 10bit-addresses. | 470 | * reads, writes as well as 10bit-addresses. |
480 | * returns: | 471 | * returns: |
481 | * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set | 472 | * 0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set |
482 | * -x an error occurred (like: -ENXIO if the device did not answer, or | 473 | * -x an error occurred (like: -EREMOTEIO if the device did not answer, or |
483 | * -ETIMEDOUT, for example if the lines are stuck...) | 474 | * -ETIMEDOUT, for example if the lines are stuck...) |
484 | */ | 475 | */ |
485 | static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | 476 | static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) |
@@ -502,14 +493,14 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
502 | if ((ret != 1) && !nak_ok) { | 493 | if ((ret != 1) && !nak_ok) { |
503 | dev_err(&i2c_adap->dev, | 494 | dev_err(&i2c_adap->dev, |
504 | "died at extended address code\n"); | 495 | "died at extended address code\n"); |
505 | return -ENXIO; | 496 | return -EREMOTEIO; |
506 | } | 497 | } |
507 | /* the remaining 8 bit address */ | 498 | /* the remaining 8 bit address */ |
508 | ret = i2c_outb(i2c_adap, msg->addr & 0xff); | 499 | ret = i2c_outb(i2c_adap, msg->addr & 0xff); |
509 | if ((ret != 1) && !nak_ok) { | 500 | if ((ret != 1) && !nak_ok) { |
510 | /* the chip did not ack / xmission error occurred */ | 501 | /* the chip did not ack / xmission error occurred */ |
511 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); | 502 | dev_err(&i2c_adap->dev, "died at 2nd address code\n"); |
512 | return -ENXIO; | 503 | return -EREMOTEIO; |
513 | } | 504 | } |
514 | if (flags & I2C_M_RD) { | 505 | if (flags & I2C_M_RD) { |
515 | bit_dbg(3, &i2c_adap->dev, "emitting repeated " | 506 | bit_dbg(3, &i2c_adap->dev, "emitting repeated " |
@@ -521,7 +512,7 @@ static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) | |||
521 | if ((ret != 1) && !nak_ok) { | 512 | if ((ret != 1) && !nak_ok) { |
522 | dev_err(&i2c_adap->dev, | 513 | dev_err(&i2c_adap->dev, |
523 | "died at repeated address code\n"); | 514 | "died at repeated address code\n"); |
524 | return -EIO; | 515 | return -EREMOTEIO; |
525 | } | 516 | } |
526 | } | 517 | } |
527 | } else { /* normal 7bit address */ | 518 | } else { /* normal 7bit address */ |
@@ -579,7 +570,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
579 | ret, ret == 1 ? "" : "s"); | 570 | ret, ret == 1 ? "" : "s"); |
580 | if (ret < pmsg->len) { | 571 | if (ret < pmsg->len) { |
581 | if (ret >= 0) | 572 | if (ret >= 0) |
582 | ret = -EIO; | 573 | ret = -EREMOTEIO; |
583 | goto bailout; | 574 | goto bailout; |
584 | } | 575 | } |
585 | } else { | 576 | } else { |
@@ -590,7 +581,7 @@ static int bit_xfer(struct i2c_adapter *i2c_adap, | |||
590 | ret, ret == 1 ? "" : "s"); | 581 | ret, ret == 1 ? "" : "s"); |
591 | if (ret < pmsg->len) { | 582 | if (ret < pmsg->len) { |
592 | if (ret >= 0) | 583 | if (ret >= 0) |
593 | ret = -EIO; | 584 | ret = -EREMOTEIO; |
594 | goto bailout; | 585 | goto bailout; |
595 | } | 586 | } |
596 | } | 587 | } |
@@ -608,7 +599,7 @@ bailout: | |||
608 | 599 | ||
609 | static u32 bit_func(struct i2c_adapter *adap) | 600 | static u32 bit_func(struct i2c_adapter *adap) |
610 | { | 601 | { |
611 | return I2C_FUNC_I2C | I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_EMUL | | 602 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
612 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | 603 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
613 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | 604 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | |
614 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; | 605 | I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING; |
@@ -617,11 +608,10 @@ static u32 bit_func(struct i2c_adapter *adap) | |||
617 | 608 | ||
618 | /* -----exported algorithm data: ------------------------------------- */ | 609 | /* -----exported algorithm data: ------------------------------------- */ |
619 | 610 | ||
620 | const struct i2c_algorithm i2c_bit_algo = { | 611 | static const struct i2c_algorithm i2c_bit_algo = { |
621 | .master_xfer = bit_xfer, | 612 | .master_xfer = bit_xfer, |
622 | .functionality = bit_func, | 613 | .functionality = bit_func, |
623 | }; | 614 | }; |
624 | EXPORT_SYMBOL(i2c_bit_algo); | ||
625 | 615 | ||
626 | /* | 616 | /* |
627 | * registering functions to load algorithms at runtime | 617 | * registering functions to load algorithms at runtime |
@@ -634,7 +624,7 @@ static int __i2c_bit_add_bus(struct i2c_adapter *adap, | |||
634 | 624 | ||
635 | if (bit_test) { | 625 | if (bit_test) { |
636 | ret = test_bus(adap); | 626 | ret = test_bus(adap); |
637 | if (bit_test >= 2 && ret < 0) | 627 | if (ret < 0) |
638 | return -ENODEV; | 628 | return -ENODEV; |
639 | } | 629 | } |
640 | 630 | ||
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index f892a424009..4ca9cf9cde7 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -15,8 +15,7 @@ | |||
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | * MA 02110-1301 USA. | ||
20 | */ | 19 | */ |
21 | 20 | ||
22 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
@@ -46,19 +45,14 @@ static int i2c_debug; | |||
46 | #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val) | 45 | #define pca_set_con(adap, val) pca_outw(adap, I2C_PCA_CON, val) |
47 | #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON) | 46 | #define pca_get_con(adap) pca_inw(adap, I2C_PCA_CON) |
48 | #define pca_wait(adap) adap->wait_for_completion(adap->data) | 47 | #define pca_wait(adap) adap->wait_for_completion(adap->data) |
48 | #define pca_reset(adap) adap->reset_chip(adap->data) | ||
49 | 49 | ||
50 | static void pca_reset(struct i2c_algo_pca_data *adap) | 50 | static void pca9665_reset(void *pd) |
51 | { | 51 | { |
52 | if (adap->chip == I2C_PCA_CHIP_9665) { | 52 | struct i2c_algo_pca_data *adap = pd; |
53 | /* Ignore the reset function from the module, | 53 | pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); |
54 | * we can use the parallel bus reset. | 54 | pca_outw(adap, I2C_PCA_IND, 0xA5); |
55 | */ | 55 | pca_outw(adap, I2C_PCA_IND, 0x5A); |
56 | pca_outw(adap, I2C_PCA_INDPTR, I2C_PCA_IPRESET); | ||
57 | pca_outw(adap, I2C_PCA_IND, 0xA5); | ||
58 | pca_outw(adap, I2C_PCA_IND, 0x5A); | ||
59 | } else { | ||
60 | adap->reset_chip(adap->data); | ||
61 | } | ||
62 | } | 56 | } |
63 | 57 | ||
64 | /* | 58 | /* |
@@ -202,7 +196,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | |||
202 | } else { | 196 | } else { |
203 | dev_dbg(&i2c_adap->dev, "bus is not idle. status is " | 197 | dev_dbg(&i2c_adap->dev, "bus is not idle. status is " |
204 | "%#04x\n", state); | 198 | "%#04x\n", state); |
205 | return -EBUSY; | 199 | return -EAGAIN; |
206 | } | 200 | } |
207 | } | 201 | } |
208 | 202 | ||
@@ -230,7 +224,7 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | |||
230 | } | 224 | } |
231 | 225 | ||
232 | curmsg = 0; | 226 | curmsg = 0; |
233 | ret = -EIO; | 227 | ret = -EREMOTEIO; |
234 | while (curmsg < num) { | 228 | while (curmsg < num) { |
235 | state = pca_status(adap); | 229 | state = pca_status(adap); |
236 | 230 | ||
@@ -265,7 +259,6 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | |||
265 | case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ | 259 | case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ |
266 | DEB2("NOT ACK received after SLA+W\n"); | 260 | DEB2("NOT ACK received after SLA+W\n"); |
267 | pca_stop(adap); | 261 | pca_stop(adap); |
268 | ret = -ENXIO; | ||
269 | goto out; | 262 | goto out; |
270 | 263 | ||
271 | case 0x40: /* SLA+R has been transmitted; ACK has been received */ | 264 | case 0x40: /* SLA+R has been transmitted; ACK has been received */ |
@@ -290,7 +283,6 @@ static int pca_xfer(struct i2c_adapter *i2c_adap, | |||
290 | case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ | 283 | case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ |
291 | DEB2("NOT ACK received after SLA+R\n"); | 284 | DEB2("NOT ACK received after SLA+R\n"); |
292 | pca_stop(adap); | 285 | pca_stop(adap); |
293 | ret = -ENXIO; | ||
294 | goto out; | 286 | goto out; |
295 | 287 | ||
296 | case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ | 288 | case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ |
@@ -383,12 +375,11 @@ static unsigned int pca_probe_chip(struct i2c_adapter *adap) | |||
383 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); | 375 | pca_outw(pca_data, I2C_PCA_INDPTR, I2C_PCA_IADR); |
384 | if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { | 376 | if (pca_inw(pca_data, I2C_PCA_IND) == 0xAA) { |
385 | printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); | 377 | printk(KERN_INFO "%s: PCA9665 detected.\n", adap->name); |
386 | pca_data->chip = I2C_PCA_CHIP_9665; | 378 | return I2C_PCA_CHIP_9665; |
387 | } else { | 379 | } else { |
388 | printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); | 380 | printk(KERN_INFO "%s: PCA9564 detected.\n", adap->name); |
389 | pca_data->chip = I2C_PCA_CHIP_9564; | 381 | return I2C_PCA_CHIP_9564; |
390 | } | 382 | } |
391 | return pca_data->chip; | ||
392 | } | 383 | } |
393 | 384 | ||
394 | static int pca_init(struct i2c_adapter *adap) | 385 | static int pca_init(struct i2c_adapter *adap) |
@@ -462,6 +453,11 @@ static int pca_init(struct i2c_adapter *adap) | |||
462 | */ | 453 | */ |
463 | int raise_fall_time; | 454 | int raise_fall_time; |
464 | 455 | ||
456 | /* Ignore the reset function from the module, | ||
457 | * we can use the parallel bus reset | ||
458 | */ | ||
459 | pca_data->reset_chip = pca9665_reset; | ||
460 | |||
465 | if (pca_data->i2c_clock > 1265800) { | 461 | if (pca_data->i2c_clock > 1265800) { |
466 | printk(KERN_WARNING "%s: I2C clock speed too high." | 462 | printk(KERN_WARNING "%s: I2C clock speed too high." |
467 | " Using 1265.8kHz.\n", adap->name); | 463 | " Using 1265.8kHz.\n", adap->name); |
@@ -477,17 +473,17 @@ static int pca_init(struct i2c_adapter *adap) | |||
477 | /* To avoid integer overflow, use clock/100 for calculations */ | 473 | /* To avoid integer overflow, use clock/100 for calculations */ |
478 | clock = pca_clock(pca_data) / 100; | 474 | clock = pca_clock(pca_data) / 100; |
479 | 475 | ||
480 | if (pca_data->i2c_clock > 1000000) { | 476 | if (pca_data->i2c_clock > 10000) { |
481 | mode = I2C_PCA_MODE_TURBO; | 477 | mode = I2C_PCA_MODE_TURBO; |
482 | min_tlow = 14; | 478 | min_tlow = 14; |
483 | min_thi = 5; | 479 | min_thi = 5; |
484 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 480 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
485 | } else if (pca_data->i2c_clock > 400000) { | 481 | } else if (pca_data->i2c_clock > 4000) { |
486 | mode = I2C_PCA_MODE_FASTP; | 482 | mode = I2C_PCA_MODE_FASTP; |
487 | min_tlow = 17; | 483 | min_tlow = 17; |
488 | min_thi = 9; | 484 | min_thi = 9; |
489 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 485 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
490 | } else if (pca_data->i2c_clock > 100000) { | 486 | } else if (pca_data->i2c_clock > 1000) { |
491 | mode = I2C_PCA_MODE_FAST; | 487 | mode = I2C_PCA_MODE_FAST; |
492 | min_tlow = 44; | 488 | min_tlow = 44; |
493 | min_thi = 20; | 489 | min_thi = 20; |
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 5c2379522aa..5eebf562ff3 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c | |||
@@ -16,8 +16,7 @@ | |||
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | * MA 02110-1301 USA. | ||
21 | * | 20 | * |
22 | * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and | 21 | * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and |
23 | * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey | 22 | * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey |
diff --git a/drivers/i2c/algos/i2c-algo-pcf.h b/drivers/i2c/algos/i2c-algo-pcf.h index 1ec703ee788..5263a9eeb8d 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.h +++ b/drivers/i2c/algos/i2c-algo-pcf.h | |||
@@ -16,8 +16,7 @@ | |||
16 | 16 | ||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License |
18 | along with this program; if not, write to the Free Software | 18 | along with this program; if not, write to the Free Software |
19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, | 19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
20 | MA 02110-1301 USA. */ | ||
21 | /* -------------------------------------------------------------------- */ | 20 | /* -------------------------------------------------------------------- */ |
22 | 21 | ||
23 | /* With some changes from Frodo Looijaard <frodol@dds.nl> */ | 22 | /* With some changes from Frodo Looijaard <frodol@dds.nl> */ |