| 2655 | | # $_[1]: The name of the adapter, as appearing in /sys/class/i2c-adapter |
| 2656 | | # $_[2]: The driver of the adapter |
| 2657 | | # @_[3]: Addresses not to scan (array reference) |
| 2658 | | sub scan_adapter |
| 2659 | | { |
| 2660 | | my ($adapter_nr, $adapter_name, $adapter_driver, $not_to_scan) = @_; |
| 2661 | | my ($funcs, $chip, $addr, $conf, @chips, $new_hash, $other_addr); |
| | 2655 | # $_[1]: Address |
| | 2656 | sub add_busy_i2c_address |
| | 2657 | { |
| | 2658 | my ($adapter_nr, $addr) = @_; |
| | 2659 | # If the address is busy, we can normally find out which driver |
| | 2660 | # requested it (if the kernel is recent enough, at least 2.6.16 and |
| | 2661 | # later are known to work), and we assume it is the right one. |
| | 2662 | my ($device, $driver, $new_hash); |
| | 2663 | |
| | 2664 | $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x", |
| | 2665 | $adapter_nr, $addr); |
| | 2666 | $driver = sysfs_device_driver($device); |
| | 2667 | |
| | 2668 | if (!defined($driver)) { |
| | 2669 | printf("Client at address 0x%02x can not be probed - ". |
| | 2670 | "unload all client drivers first!\n", $addr); |
| | 2671 | return; |
| | 2672 | } |
| | 2673 | |
| | 2674 | $new_hash = { |
| | 2675 | conf => 6, # Arbitrary confidence |
| | 2676 | i2c_addr => $addr, |
| | 2677 | chipname => sysfs_device_attribute($device, "name") |
| | 2678 | || "unknown", |
| | 2679 | i2c_adap => $i2c_adapters[$adapter_nr]->{name}, |
| | 2680 | i2c_driver => $i2c_adapters[$adapter_nr]->{driver}, |
| | 2681 | i2c_devnr => $adapter_nr, |
| | 2682 | }; |
| | 2683 | |
| | 2684 | printf "Client found at address 0x\%02x\n", $addr; |
| | 2685 | printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n", |
| | 2686 | $driver, $new_hash->{chipname}; |
| | 2687 | |
| | 2688 | # Only add it to the list if this is something we would have detected, |
| | 2689 | # else we end up with random i2c chip drivers listed (for example |
| | 2690 | # media/video drivers.) |
| | 2691 | if (exists $modules_supported{$driver}) { |
| | 2692 | add_i2c_to_chips_detected($driver, $new_hash); |
| | 2693 | } else { |
| | 2694 | print " (note: this is probably NOT a sensor chip!)\n"; |
| | 2695 | } |
| | 2696 | } |
| | 2697 | |
| | 2698 | # $_[0]: The number of the adapter to scan |
| | 2699 | # $_[1]: Address |
| | 2700 | # $_[2]: Chip being probed |
| | 2701 | sub probe_free_i2c_address |
| | 2702 | { |
| | 2703 | my ($adapter_nr, $addr, $chip) = @_; |
| | 2704 | my ($conf, @other_addr, $new_hash); |
| | 2705 | |
| | 2706 | printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name})); |
| | 2707 | if (($conf, @other_addr) = &{$chip->{i2c_detect}} (\*FILE, $addr)) { |
| | 2708 | if ($chip->{driver} eq "not-a-sensor") { |
| | 2709 | print "Yes\n", |
| | 2710 | " (confidence $conf, not a hardware monitoring chip"; |
| | 2711 | } else { |
| | 2712 | print "Success!\n", |
| | 2713 | " (confidence $conf, driver `$chip->{driver}'"; |
| | 2714 | } |
| | 2715 | if (@other_addr) { |
| | 2716 | print ", other addresses:"; |
| | 2717 | @other_addr = sort @other_addr; |
| | 2718 | foreach my $other_addr (@other_addr) { |
| | 2719 | printf(" 0x%02x", $other_addr); |
| | 2720 | } |
| | 2721 | } |
| | 2722 | print ")\n"; |
| | 2723 | |
| | 2724 | return if ($chip->{driver} eq "not-a-sensor" |
| | 2725 | || $chip->{driver} eq "use-isa-instead"); |
| | 2726 | |
| | 2727 | $new_hash = { |
| | 2728 | conf => $conf, |
| | 2729 | i2c_addr => $addr, |
| | 2730 | chipname => $chip->{name}, |
| | 2731 | i2c_adap => $i2c_adapters[$adapter_nr]->{name}, |
| | 2732 | i2c_driver => $i2c_adapters[$adapter_nr]->{driver}, |
| | 2733 | i2c_devnr => $adapter_nr, |
| | 2734 | }; |
| | 2735 | if (@other_addr) { |
| | 2736 | my @other_addr_copy = @other_addr; |
| | 2737 | $new_hash->{i2c_sub_addrs} = \@other_addr_copy; |
| | 2738 | } |
| | 2739 | add_i2c_to_chips_detected($chip->{driver}, $new_hash); |
| | 2740 | } else { |
| | 2741 | print "No\n"; |
| | 2742 | } |
| | 2743 | } |
| | 2744 | |
| | 2745 | # $_[0]: The number of the adapter to scan |
| | 2746 | # $_[1]: Addresses not to scan (array reference) |
| | 2747 | sub scan_i2c_adapter |
| | 2748 | { |
| | 2749 | my ($adapter_nr, $not_to_scan) = @_; |
| | 2750 | my ($funcs, $chip, $addr); |
| 2696 | | # If the address is busy, we can normally find out |
| 2697 | | # which driver requested it (if the kernel is recent |
| 2698 | | # enough, at least 2.6.16 and later are known to work), |
| 2699 | | # and we assume it is the right one. |
| 2700 | | my ($device, $driver); |
| 2701 | | |
| 2702 | | $device = sprintf("$sysfs_root/bus/i2c/devices/\%d-\%04x", |
| 2703 | | $adapter_nr, $addr); |
| 2704 | | $driver = sysfs_device_driver($device); |
| 2705 | | |
| 2706 | | if (defined($driver)) { |
| 2707 | | $new_hash = { |
| 2708 | | conf => 6, # Arbitrary confidence |
| 2709 | | i2c_addr => $addr, |
| 2710 | | chipname => sysfs_device_attribute($device, "name") |
| 2711 | | || "unknown", |
| 2712 | | i2c_adap => $adapter_name, |
| 2713 | | i2c_driver => $adapter_driver, |
| 2714 | | i2c_devnr => $adapter_nr, |
| 2715 | | }; |
| 2716 | | |
| 2717 | | printf "Client found at address 0x\%02x\n", $addr; |
| 2718 | | printf "Handled by driver `\%s' (already loaded), chip type `\%s'\n", |
| 2719 | | $driver, $new_hash->{chipname}; |
| 2720 | | |
| 2721 | | # Only add it to the list if this is something |
| 2722 | | # we would have detected, else we end up with |
| 2723 | | # random i2c chip drivers listed (for example |
| 2724 | | # media/video drivers.) |
| 2725 | | if (exists $modules_supported{$driver}) { |
| 2726 | | add_i2c_to_chips_detected($driver, $new_hash); |
| 2727 | | } else { |
| 2728 | | print " (note: this is probably NOT a sensor chip!)\n"; |
| 2729 | | } |
| 2730 | | } else { |
| 2731 | | printf("Client at address 0x%02x can not be probed - ". |
| 2732 | | "unload all client drivers first!\n", $addr); |
| 2733 | | } |
| | 2785 | add_busy_i2c_address($adapter_nr, $addr); |
| 2746 | | if (exists $chip->{i2c_addrs} and contains($addr, @{$chip->{i2c_addrs}})) { |
| 2747 | | printf("\%-60s", sprintf("Probing for `\%s'... ", $chip->{name})); |
| 2748 | | if (($conf, @chips) = &{$chip->{i2c_detect}} (\*FILE, $addr)) { |
| 2749 | | if ($chip->{driver} eq "not-a-sensor") { |
| 2750 | | print "Yes\n", |
| 2751 | | " (confidence $conf, not a hardware monitoring chip"; |
| 2752 | | } else { |
| 2753 | | print "Success!\n", |
| 2754 | | " (confidence $conf, driver `$chip->{driver}'"; |
| 2755 | | } |
| 2756 | | if (@chips) { |
| 2757 | | print ", other addresses:"; |
| 2758 | | @chips = sort @chips; |
| 2759 | | foreach $other_addr (@chips) { |
| 2760 | | printf(" 0x%02x", $other_addr); |
| 2761 | | } |
| 2762 | | } |
| 2763 | | printf ")\n"; |
| 2764 | | |
| 2765 | | next if ($chip->{driver} eq "not-a-sensor" |
| 2766 | | || $chip->{driver} eq "use-isa-instead"); |
| 2767 | | |
| 2768 | | $new_hash = { |
| 2769 | | conf => $conf, |
| 2770 | | i2c_addr => $addr, |
| 2771 | | chipname => $chip->{name}, |
| 2772 | | i2c_adap => $adapter_name, |
| 2773 | | i2c_driver => $adapter_driver, |
| 2774 | | i2c_devnr => $adapter_nr, |
| 2775 | | }; |
| 2776 | | if (@chips) { |
| 2777 | | my @chips_copy = @chips; |
| 2778 | | $new_hash->{i2c_sub_addrs} = \@chips_copy; |
| 2779 | | } |
| 2780 | | add_i2c_to_chips_detected($chip->{driver}, $new_hash); |
| 2781 | | } else { |
| 2782 | | print "No\n"; |
| 2783 | | } |
| 2784 | | } |
| | 2798 | next unless exists $chip->{i2c_addrs} |
| | 2799 | && contains($addr, @{$chip->{i2c_addrs}}); |
| | 2800 | probe_free_i2c_address($adapter_nr, $addr, $chip); |