diff options
-rw-r--r-- | Documentation/i2c/writing-clients | 7 | ||||
-rw-r--r-- | drivers/i2c/i2c-core.c | 165 |
2 files changed, 93 insertions, 79 deletions
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients index 97e138cbb2a9..077275722a7c 100644 --- a/Documentation/i2c/writing-clients +++ b/Documentation/i2c/writing-clients | |||
@@ -241,9 +241,10 @@ Below, some things are only needed if this is a `sensors' driver. Those | |||
241 | parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */ | 241 | parts are between /* SENSORS ONLY START */ and /* SENSORS ONLY END */ |
242 | markers. | 242 | markers. |
243 | 243 | ||
244 | This function should only return an error (any value != 0) if there is | 244 | Returning an error different from -ENODEV in a detect function will cause |
245 | some reason why no more detection should be done anymore. If the | 245 | the detection to stop: other addresses and adapters won't be scanned. |
246 | detection just fails for this address, return 0. | 246 | This should only be done on fatal or internal errors, such as a memory |
247 | shortage or i2c_attach_client failing. | ||
247 | 248 | ||
248 | For now, you can ignore the `flags' parameter. It is there for future use. | 249 | For now, you can ignore the `flags' parameter. It is there for future use. |
249 | 250 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 372b5996d045..bee0148dfab8 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -662,107 +662,120 @@ int i2c_control(struct i2c_client *client, | |||
662 | * Will not work for 10-bit addresses! | 662 | * Will not work for 10-bit addresses! |
663 | * ---------------------------------------------------- | 663 | * ---------------------------------------------------- |
664 | */ | 664 | */ |
665 | /* Return: kind (>= 0) if force found, -1 if not found */ | 665 | static int i2c_probe_address(struct i2c_adapter *adapter, int addr, int kind, |
666 | static inline int i2c_probe_forces(struct i2c_adapter *adapter, int addr, | 666 | int (*found_proc) (struct i2c_adapter *, int, int)) |
667 | unsigned short **forces) | ||
668 | { | 667 | { |
669 | unsigned short kind; | 668 | int err; |
670 | int j, adap_id = i2c_adapter_id(adapter); | 669 | |
671 | 670 | /* Make sure the address is valid */ | |
672 | for (kind = 0; forces[kind]; kind++) { | 671 | if (addr < 0x03 || addr > 0x77) { |
673 | for (j = 0; forces[kind][j] != I2C_CLIENT_END; j += 2) { | 672 | dev_warn(&adapter->dev, "Invalid probe address 0x%02x\n", |
674 | if ((forces[kind][j] == adap_id || | 673 | addr); |
675 | forces[kind][j] == ANY_I2C_BUS) | 674 | return -EINVAL; |
676 | && forces[kind][j + 1] == addr) { | ||
677 | dev_dbg(&adapter->dev, "found force parameter, " | ||
678 | "addr 0x%02x, kind %u\n", addr, kind); | ||
679 | return kind; | ||
680 | } | ||
681 | } | ||
682 | } | 675 | } |
683 | 676 | ||
684 | return -1; | 677 | /* Skip if already in use */ |
678 | if (i2c_check_addr(adapter, addr)) | ||
679 | return 0; | ||
680 | |||
681 | /* Make sure there is something at this address, unless forced */ | ||
682 | if (kind < 0 | ||
683 | && i2c_smbus_xfer(adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0) | ||
684 | return 0; | ||
685 | |||
686 | /* Finally call the custom detection function */ | ||
687 | err = found_proc(adapter, addr, kind); | ||
688 | |||
689 | /* -ENODEV can be returned if there is a chip at the given address | ||
690 | but it isn't supported by this chip driver. We catch it here as | ||
691 | this isn't an error. */ | ||
692 | return (err == -ENODEV) ? 0 : err; | ||
685 | } | 693 | } |
686 | 694 | ||
687 | int i2c_probe(struct i2c_adapter *adapter, | 695 | int i2c_probe(struct i2c_adapter *adapter, |
688 | struct i2c_client_address_data *address_data, | 696 | struct i2c_client_address_data *address_data, |
689 | int (*found_proc) (struct i2c_adapter *, int, int)) | 697 | int (*found_proc) (struct i2c_adapter *, int, int)) |
690 | { | 698 | { |
691 | int addr,i,found,err; | 699 | int i, err; |
692 | int adap_id = i2c_adapter_id(adapter); | 700 | int adap_id = i2c_adapter_id(adapter); |
693 | 701 | ||
694 | /* Forget it if we can't probe using SMBUS_QUICK */ | 702 | /* Forget it if we can't probe using SMBUS_QUICK */ |
695 | if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK)) | 703 | if (! i2c_check_functionality(adapter,I2C_FUNC_SMBUS_QUICK)) |
696 | return -1; | 704 | return -1; |
697 | 705 | ||
698 | for (addr = 0x00; addr <= 0x7f; addr++) { | 706 | /* Force entries are done first, and are not affected by ignore |
699 | 707 | entries */ | |
700 | /* Skip if already in use */ | 708 | if (address_data->forces) { |
701 | if (i2c_check_addr(adapter,addr)) | 709 | unsigned short **forces = address_data->forces; |
702 | continue; | 710 | int kind; |
703 | 711 | ||
704 | /* If it is in one of the force entries, we don't do any detection | 712 | for (kind = 0; forces[kind]; kind++) { |
705 | at all */ | 713 | for (i = 0; forces[kind][i] != I2C_CLIENT_END; |
706 | found = 0; | 714 | i += 2) { |
707 | 715 | if (forces[kind][i] == adap_id | |
708 | if (address_data->forces) { | 716 | || forces[kind][i] == ANY_I2C_BUS) { |
709 | int kind = i2c_probe_forces(adapter, addr, | 717 | dev_dbg(&adapter->dev, "found force " |
710 | address_data->forces); | 718 | "parameter for adapter %d, " |
711 | if (kind >= 0) { /* force found */ | 719 | "addr 0x%02x, kind %d\n", |
712 | if ((err = found_proc(adapter, addr, kind))) | 720 | adap_id, forces[kind][i + 1], |
713 | return err; | 721 | kind); |
714 | continue; | 722 | err = i2c_probe_address(adapter, |
715 | } | 723 | forces[kind][i + 1], |
716 | } | 724 | kind, found_proc); |
717 | 725 | if (err) | |
718 | /* If this address is in one of the ignores, we can forget about | 726 | return err; |
719 | it right now */ | 727 | } |
720 | for (i = 0; | ||
721 | !found && (address_data->ignore[i] != I2C_CLIENT_END); | ||
722 | i += 2) { | ||
723 | if (((adap_id == address_data->ignore[i]) || | ||
724 | ((address_data->ignore[i] == ANY_I2C_BUS))) && | ||
725 | (addr == address_data->ignore[i+1])) { | ||
726 | dev_dbg(&adapter->dev, "found ignore parameter for adapter %d, " | ||
727 | "addr %04x\n", adap_id ,addr); | ||
728 | found = 1; | ||
729 | } | 728 | } |
730 | } | 729 | } |
731 | if (found) | 730 | } |
732 | continue; | ||
733 | 731 | ||
734 | /* Now, we will do a detection, but only if it is in the normal or | 732 | /* Probe entries are done second, and are not affected by ignore |
735 | probe entries */ | 733 | entries either */ |
736 | for (i = 0; | 734 | for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) { |
737 | !found && (address_data->normal_i2c[i] != I2C_CLIENT_END); | 735 | if (address_data->probe[i] == adap_id |
738 | i += 1) { | 736 | || address_data->probe[i] == ANY_I2C_BUS) { |
739 | if (addr == address_data->normal_i2c[i]) { | 737 | dev_dbg(&adapter->dev, "found probe parameter for " |
740 | found = 1; | 738 | "adapter %d, addr 0x%02x\n", adap_id, |
741 | dev_dbg(&adapter->dev, "found normal i2c entry for adapter %d, " | 739 | address_data->probe[i + 1]); |
742 | "addr %02x\n", adap_id, addr); | 740 | err = i2c_probe_address(adapter, |
743 | } | 741 | address_data->probe[i + 1], |
742 | -1, found_proc); | ||
743 | if (err) | ||
744 | return err; | ||
744 | } | 745 | } |
746 | } | ||
745 | 747 | ||
746 | for (i = 0; | 748 | /* Normal entries are done last, unless shadowed by an ignore entry */ |
747 | !found && (address_data->probe[i] != I2C_CLIENT_END); | 749 | for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) { |
748 | i += 2) { | 750 | int j, ignore; |
749 | if (((adap_id == address_data->probe[i]) || | 751 | |
750 | ((address_data->probe[i] == ANY_I2C_BUS))) && | 752 | ignore = 0; |
751 | (addr == address_data->probe[i+1])) { | 753 | for (j = 0; address_data->ignore[j] != I2C_CLIENT_END; |
752 | found = 1; | 754 | j += 2) { |
753 | dev_dbg(&adapter->dev, "found probe parameter for adapter %d, " | 755 | if ((address_data->ignore[j] == adap_id || |
754 | "addr %04x\n", adap_id,addr); | 756 | address_data->ignore[j] == ANY_I2C_BUS) |
757 | && address_data->ignore[j + 1] | ||
758 | == address_data->normal_i2c[i]) { | ||
759 | dev_dbg(&adapter->dev, "found ignore " | ||
760 | "parameter for adapter %d, " | ||
761 | "addr 0x%02x\n", adap_id, | ||
762 | address_data->ignore[j + 1]); | ||
755 | } | 763 | } |
764 | ignore = 1; | ||
765 | break; | ||
756 | } | 766 | } |
757 | if (!found) | 767 | if (ignore) |
758 | continue; | 768 | continue; |
759 | 769 | ||
760 | /* OK, so we really should examine this address. First check | 770 | dev_dbg(&adapter->dev, "found normal entry for adapter %d, " |
761 | whether there is some client here at all! */ | 771 | "addr 0x%02x\n", adap_id, |
762 | if (i2c_smbus_xfer(adapter,addr,0,0,0,I2C_SMBUS_QUICK,NULL) >= 0) | 772 | address_data->normal_i2c[i]); |
763 | if ((err = found_proc(adapter,addr,-1))) | 773 | err = i2c_probe_address(adapter, address_data->normal_i2c[i], |
764 | return err; | 774 | -1, found_proc); |
775 | if (err) | ||
776 | return err; | ||
765 | } | 777 | } |
778 | |||
766 | return 0; | 779 | return 0; |
767 | } | 780 | } |
768 | 781 | ||