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 | ||
