+ if ( m/^device (\S+)/ ) {
+ $device = $1;
+ if ( my $replace = $serial_tty->{$device} ) {
+ $device = $replace; # replace serial hex with kernel name
+ } else {
+ $device =~ s/^[0-9a-f]*\.//; # remove hex address
+ }
+ } elsif ( m/^group (\w+\d+)/ ) {
+ $pin = $1;
+
+ } elsif ( m/^function (\S+)/ ) {
+ $function = $1;
+ } elsif ( m/^$/ ) {
+ if ( $device && $pin && $function ) {
+ push @{ $pin_function->{$pin} }, "$device $function";
+
+ annotate_pin $pin, "[$device $function]";
+ } else {
+ warn "missing one of ",dump( $device, $pin, $function );
+ }
+
+ $device = undef;
+ $pin = undef;
+ $function = undef;
+
+ }
+}
+
+warn "# pin_function = ",dump($pin_function);
+
+
+# insert kernel gpio info
+my $linux_gpio_name;
+open(my $pins_fh, '<', (glob "/sys/kernel/debug/pinctrl/*/pins")[0]);
+while(<$pins_fh>) {
+ if ( m/^pin (\d+) \(([^\)]+)\)/ ) {
+ $linux_gpio_name->{$1} = $2;
+ }
+}
+warn "# linux_gpio_name = ",dump( $linux_gpio_name );
+
+
+my $gpio_debug;
+open(my $gpio_fh, '<', '/sys/kernel/debug/gpio');
+while(<$gpio_fh>) {
+ if (m/|/ ) {
+ s/^\s+//;
+ s/\s+$//;
+ my @l = split(/\s*[\(\|\)]\s*/, $_);
+ warn "XXX ", dump( \@l );
+ if ( $l[0] =~ m/gpio-(\d+)/ ) {
+ if ( my $pin = $linux_gpio_name->{$1} ) {
+ $gpio_debug->{ $pin } = $l[2];
+ $l[3] =~ s/\s\s+/ /g;
+ annotate_pin $pin, qq{"$l[2]" $l[3]};
+ } else {
+ warn "FIXME can't find $1 in ",dump( $linux_gpio_name );
+ }
+ }
+ }
+
+}
+warn "# gpio_debug = ",dump( $gpio_debug );
+
+
+
+my $have_sunxi_pio = `which sunxi-pio`;
+if ( $have_sunxi_pio ) {
+
+open(my $pio, '-|', 'sunxi-pio -m print');
+while(<$pio>) {
+ chomp;
+ s/[<>]+/ /g;
+ my @p = split(/\s+/,$_);
+ warn "# pio ",dump(\@p);
+ # annotate input 0 and output 1 pins
+# annotate_pin $p[0], ( $p[1] ? 'O' : 'I' ) . ':' . $p[4] if $p[1] == 0 || $p[1] == 1;
+ my $pin = shift @p;
+ annotate_pin $pin, join(' ',@p) if ! $opt_svg;
+}
+close($pio);
+
+} # have_sunxi_pio
+
+my $have_raspi_gpio = `which raspi-gpio`;
+if ( $have_raspi_gpio ) {
+
+open(my $pio, '-|', 'raspi-gpio get');
+while(<$pio>) {
+ chomp;
+ if ( m/^GPIO (\d+): (.+)/ ) {
+ my $pin = 'gpio' . $1;
+ annotate_pin $pin, $2 if ! $opt_svg;
+ }
+}
+close($pio);
+
+} # have_raspi_gpio
+
+
+my $pinmux;
+my $pinmux_path = (glob("/sys/kernel/debug/pinctrl/*/pinmux-functions"))[0];
+if ( $opt_pinmux && -e $pinmux_path ) {
+ open(my $mux, '<', $pinmux_path);
+ while(<$mux>) {
+ chomp;
+ if ( m/function: (\w+), groups = \[ (.*) \]/ ) {
+ my ( $func, $pins ) = ( $1, $2 );
+ foreach ( split(/\s+/,$pins) ) {
+ push @{ $pinmux->{$_} }, $func;