diff options
Diffstat (limited to 'drivers/i2c/busses/i2c-eg20t.c')
-rw-r--r-- | drivers/i2c/busses/i2c-eg20t.c | 226 |
1 files changed, 66 insertions, 160 deletions
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index d6309e618cdc..943084a3b690 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -373,6 +373,34 @@ static void pch_i2c_stop(struct i2c_algo_pch_data *adap) | |||
373 | pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_START); | 373 | pch_clrbit(adap->pch_base_address, PCH_I2CCTL, PCH_START); |
374 | } | 374 | } |
375 | 375 | ||
376 | static int pch_i2c_wait_for_check_xfer(struct i2c_algo_pch_data *adap) | ||
377 | { | ||
378 | int rtn; | ||
379 | |||
380 | rtn = pch_i2c_wait_for_xfer_complete(adap); | ||
381 | if (rtn == 0) { | ||
382 | if (pch_i2c_getack(adap)) { | ||
383 | pch_dbg(adap, "Receive NACK for slave address" | ||
384 | "setting\n"); | ||
385 | return -EIO; | ||
386 | } | ||
387 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
388 | pch_err(adap, "Lost Arbitration\n"); | ||
389 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT); | ||
390 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT); | ||
391 | pch_i2c_init(adap); | ||
392 | return -EAGAIN; | ||
393 | } else { /* wait-event timeout */ | ||
394 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
395 | __func__, __LINE__); | ||
396 | pch_i2c_stop(adap); | ||
397 | pch_i2c_init(adap); | ||
398 | return -ETIME; | ||
399 | } | ||
400 | |||
401 | return 0; | ||
402 | } | ||
403 | |||
376 | /** | 404 | /** |
377 | * pch_i2c_repstart() - generate repeated start condition in normal mode | 405 | * pch_i2c_repstart() - generate repeated start condition in normal mode |
378 | * @adap: Pointer to struct i2c_algo_pch_data. | 406 | * @adap: Pointer to struct i2c_algo_pch_data. |
@@ -427,30 +455,12 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap, | |||
427 | if (first) | 455 | if (first) |
428 | pch_i2c_start(adap); | 456 | pch_i2c_start(adap); |
429 | 457 | ||
430 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 458 | rtn = pch_i2c_wait_for_check_xfer(adap); |
431 | if (rtn == 0) { | 459 | if (rtn) |
432 | if (pch_i2c_getack(adap)) { | 460 | return rtn; |
433 | pch_dbg(adap, "Receive NACK for slave address" | 461 | |
434 | "setting\n"); | 462 | addr_8_lsb = (addr & I2C_ADDR_MSK); |
435 | return -EIO; | 463 | iowrite32(addr_8_lsb, p + PCH_I2CDR); |
436 | } | ||
437 | addr_8_lsb = (addr & I2C_ADDR_MSK); | ||
438 | iowrite32(addr_8_lsb, p + PCH_I2CDR); | ||
439 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
440 | pch_err(adap, "Lost Arbitration\n"); | ||
441 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
442 | I2CMAL_BIT); | ||
443 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
444 | I2CMIF_BIT); | ||
445 | pch_i2c_init(adap); | ||
446 | return -EAGAIN; | ||
447 | } else { /* wait-event timeout */ | ||
448 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
449 | __func__, __LINE__); | ||
450 | pch_i2c_stop(adap); | ||
451 | pch_i2c_init(adap); | ||
452 | return -ETIME; | ||
453 | } | ||
454 | } else { | 464 | } else { |
455 | /* set 7 bit slave address and R/W bit as 0 */ | 465 | /* set 7 bit slave address and R/W bit as 0 */ |
456 | iowrite32(addr << 1, p + PCH_I2CDR); | 466 | iowrite32(addr << 1, p + PCH_I2CDR); |
@@ -458,50 +468,21 @@ static s32 pch_i2c_writebytes(struct i2c_adapter *i2c_adap, | |||
458 | pch_i2c_start(adap); | 468 | pch_i2c_start(adap); |
459 | } | 469 | } |
460 | 470 | ||
461 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 471 | rtn = pch_i2c_wait_for_check_xfer(adap); |
462 | if (rtn == 0) { | 472 | if (rtn) |
463 | if (pch_i2c_getack(adap)) { | 473 | return rtn; |
464 | pch_dbg(adap, "Receive NACK for slave address" | ||
465 | "setting\n"); | ||
466 | return -EIO; | ||
467 | } | ||
468 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
469 | pch_err(adap, "Lost Arbitration\n"); | ||
470 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT); | ||
471 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT); | ||
472 | pch_i2c_init(adap); | ||
473 | return -EAGAIN; | ||
474 | } else { /* wait-event timeout */ | ||
475 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
476 | __func__, __LINE__); | ||
477 | pch_i2c_stop(adap); | ||
478 | pch_i2c_init(adap); | ||
479 | return -ETIME; | ||
480 | } | ||
481 | 474 | ||
482 | for (wrcount = 0; wrcount < length; ++wrcount) { | 475 | for (wrcount = 0; wrcount < length; ++wrcount) { |
483 | /* write buffer value to I2C data register */ | 476 | /* write buffer value to I2C data register */ |
484 | iowrite32(buf[wrcount], p + PCH_I2CDR); | 477 | iowrite32(buf[wrcount], p + PCH_I2CDR); |
485 | pch_dbg(adap, "writing %x to Data register\n", buf[wrcount]); | 478 | pch_dbg(adap, "writing %x to Data register\n", buf[wrcount]); |
486 | 479 | ||
487 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 480 | rtn = pch_i2c_wait_for_check_xfer(adap); |
488 | if (rtn == 0) { | 481 | if (rtn) |
489 | if (pch_i2c_getack(adap)) { | 482 | return rtn; |
490 | pch_dbg(adap, "Receive NACK for slave address" | 483 | |
491 | "setting\n"); | 484 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMCF_BIT); |
492 | return -EIO; | 485 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT); |
493 | } | ||
494 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
495 | I2CMCF_BIT); | ||
496 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
497 | I2CMIF_BIT); | ||
498 | } else { /* wait-event timeout */ | ||
499 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
500 | __func__, __LINE__); | ||
501 | pch_i2c_stop(adap); | ||
502 | pch_i2c_init(adap); | ||
503 | return -ETIME; | ||
504 | } | ||
505 | } | 486 | } |
506 | 487 | ||
507 | /* check if this is the last message */ | 488 | /* check if this is the last message */ |
@@ -589,56 +570,21 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
589 | if (first) | 570 | if (first) |
590 | pch_i2c_start(adap); | 571 | pch_i2c_start(adap); |
591 | 572 | ||
592 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 573 | rtn = pch_i2c_wait_for_check_xfer(adap); |
593 | if (rtn == 0) { | 574 | if (rtn) |
594 | if (pch_i2c_getack(adap)) { | 575 | return rtn; |
595 | pch_dbg(adap, "Receive NACK for slave address" | 576 | |
596 | "setting\n"); | 577 | addr_8_lsb = (addr & I2C_ADDR_MSK); |
597 | return -EIO; | 578 | iowrite32(addr_8_lsb, p + PCH_I2CDR); |
598 | } | 579 | |
599 | addr_8_lsb = (addr & I2C_ADDR_MSK); | ||
600 | iowrite32(addr_8_lsb, p + PCH_I2CDR); | ||
601 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
602 | pch_err(adap, "Lost Arbitration\n"); | ||
603 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
604 | I2CMAL_BIT); | ||
605 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
606 | I2CMIF_BIT); | ||
607 | pch_i2c_init(adap); | ||
608 | return -EAGAIN; | ||
609 | } else { /* wait-event timeout */ | ||
610 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
611 | __func__, __LINE__); | ||
612 | pch_i2c_stop(adap); | ||
613 | pch_i2c_init(adap); | ||
614 | return -ETIME; | ||
615 | } | ||
616 | pch_i2c_restart(adap); | 580 | pch_i2c_restart(adap); |
617 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 581 | |
618 | if (rtn == 0) { | 582 | rtn = pch_i2c_wait_for_check_xfer(adap); |
619 | if (pch_i2c_getack(adap)) { | 583 | if (rtn) |
620 | pch_dbg(adap, "Receive NACK for slave address" | 584 | return rtn; |
621 | "setting\n"); | 585 | |
622 | return -EIO; | 586 | addr_2_msb |= I2C_RD; |
623 | } | 587 | iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, p + PCH_I2CDR); |
624 | addr_2_msb |= I2C_RD; | ||
625 | iowrite32(addr_2_msb | TEN_BIT_ADDR_MASK, | ||
626 | p + PCH_I2CDR); | ||
627 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
628 | pch_err(adap, "Lost Arbitration\n"); | ||
629 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
630 | I2CMAL_BIT); | ||
631 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, | ||
632 | I2CMIF_BIT); | ||
633 | pch_i2c_init(adap); | ||
634 | return -EAGAIN; | ||
635 | } else { /* wait-event timeout */ | ||
636 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
637 | __func__, __LINE__); | ||
638 | pch_i2c_stop(adap); | ||
639 | pch_i2c_init(adap); | ||
640 | return -ETIME; | ||
641 | } | ||
642 | } else { | 588 | } else { |
643 | /* 7 address bits + R/W bit */ | 589 | /* 7 address bits + R/W bit */ |
644 | addr = (((addr) << 1) | (I2C_RD)); | 590 | addr = (((addr) << 1) | (I2C_RD)); |
@@ -649,26 +595,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
649 | if (first) | 595 | if (first) |
650 | pch_i2c_start(adap); | 596 | pch_i2c_start(adap); |
651 | 597 | ||
652 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 598 | rtn = pch_i2c_wait_for_check_xfer(adap); |
653 | if (rtn == 0) { | 599 | if (rtn) |
654 | if (pch_i2c_getack(adap)) { | 600 | return rtn; |
655 | pch_dbg(adap, "Receive NACK for slave address" | ||
656 | "setting\n"); | ||
657 | return -EIO; | ||
658 | } | ||
659 | } else if (rtn == -EIO) { /* Arbitration Lost */ | ||
660 | pch_err(adap, "Lost Arbitration\n"); | ||
661 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMAL_BIT); | ||
662 | pch_clrbit(adap->pch_base_address, PCH_I2CSR, I2CMIF_BIT); | ||
663 | pch_i2c_init(adap); | ||
664 | return -EAGAIN; | ||
665 | } else { /* wait-event timeout */ | ||
666 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
667 | __func__, __LINE__); | ||
668 | pch_i2c_stop(adap); | ||
669 | pch_i2c_init(adap); | ||
670 | return -ETIME; | ||
671 | } | ||
672 | 601 | ||
673 | if (length == 0) { | 602 | if (length == 0) { |
674 | pch_i2c_stop(adap); | 603 | pch_i2c_stop(adap); |
@@ -687,21 +616,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
687 | if (loop != 1) | 616 | if (loop != 1) |
688 | read_index++; | 617 | read_index++; |
689 | 618 | ||
690 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 619 | rtn = pch_i2c_wait_for_check_xfer(adap); |
691 | if (rtn == 0) { | 620 | if (rtn) |
692 | if (pch_i2c_getack(adap)) { | 621 | return rtn; |
693 | pch_dbg(adap, "Receive NACK for slave" | ||
694 | "address setting\n"); | ||
695 | return -EIO; | ||
696 | } | ||
697 | } else { /* wait-event timeout */ | ||
698 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
699 | __func__, __LINE__); | ||
700 | pch_i2c_stop(adap); | ||
701 | pch_i2c_init(adap); | ||
702 | return -ETIME; | ||
703 | } | ||
704 | |||
705 | } /* end for */ | 622 | } /* end for */ |
706 | 623 | ||
707 | pch_i2c_sendnack(adap); | 624 | pch_i2c_sendnack(adap); |
@@ -711,20 +628,9 @@ static s32 pch_i2c_readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
711 | if (length != 1) | 628 | if (length != 1) |
712 | read_index++; | 629 | read_index++; |
713 | 630 | ||
714 | rtn = pch_i2c_wait_for_xfer_complete(adap); | 631 | rtn = pch_i2c_wait_for_check_xfer(adap); |
715 | if (rtn == 0) { | 632 | if (rtn) |
716 | if (pch_i2c_getack(adap)) { | 633 | return rtn; |
717 | pch_dbg(adap, "Receive NACK for slave" | ||
718 | "address setting\n"); | ||
719 | return -EIO; | ||
720 | } | ||
721 | } else { /* wait-event timeout */ | ||
722 | pch_err(adap, "%s(L.%d):wait-event timeout\n", | ||
723 | __func__, __LINE__); | ||
724 | pch_i2c_stop(adap); | ||
725 | pch_i2c_init(adap); | ||
726 | return -ETIME; | ||
727 | } | ||
728 | 634 | ||
729 | if (last) | 635 | if (last) |
730 | pch_i2c_stop(adap); | 636 | pch_i2c_stop(adap); |