#!/usr/bin/env bash

wait_writeable() {
   while [ ! -w "/sys/class/gpio/gpio$1/direction" ]; do
      sleep .01
   done
}

KERNEL_VER=$(uname -r | cut -f1 -d.)

#Files are in same directory as script
dir="$(dirname "$BASH_SOURCE")"
if [ "$KERNEL_VER" -lt "4" ]; then
   # Use legacy cape manager loading functionality
   if [ -e /sys/devices/platform/bone_capemgr/slots ]
   then
      CAPE=/sys/devices/platform/bone_capemgr/slots
   else
      CAPE=/sys/devices/bone_capemgr.*/slots
      # Enable A/D
      echo cape-bone-iio > $CAPE
   fi
fi

pin='61'
if [ ! -d /sys/class/gpio/gpio$pin ]; then
   # Depending on default pullup since we haven't loaded the overlay
   echo $pin > /sys/class/gpio/export
   wait_writeable "$pin"
fi
echo in > /sys/class/gpio/gpio$pin/direction
REV=$(cat /sys/class/gpio/gpio$pin/value)

if [ "$REV" == "0" ]; then
   echo Rev C or D Board
   if [ "$KERNEL_VER" -lt "4" ]; then
      /usr/bin/dtc -O dtb -o $dir/emu-00C0.dtbo -b 0 -@ $dir/emu-00C0.dts
      cp $dir/emu-00C0.dtbo /lib/firmware
      echo emu:00C0 > $CAPE
   else
      # Batch configure all pins for mfm_emu
      # Shouldn't need sudo but sometimes get 
      # ERROR: open() for /sys/devices/platform/ocp/ocp:P9_13_pinmux/state failed, Permission denied
      sudo config-pin -c $dir/mfm_emu_revc.bbio
   fi
   # 31 drive1 select/recovery, 51 write fault(C)
   # 60 emulation xcvr en
   # 48 testing(C)
   pins_low="31 48 51 60"
   # 14,30(C) drive selected LEDS
   # 50 mfm read xcvr en
   pins_high="14 30 50"
else
   if [ "$KERNEL_VER" -lt "4" ]; then
      /usr/bin/dtc -O dtb -o $dir/emu-00A0.dtbo -b 0 -@ $dir/emu-00A0.dts
      cp $dir/emu-00A0.dtbo /lib/firmware
      echo emu:00A0 > $CAPE
   else
      # Shouldn't need sudo but sometimes get 
      # ERROR: open() for /sys/devices/platform/ocp/ocp:P9_13_pinmux/state failed, Permission denied
      sudo config-pin -c $dir/mfm_emu_revab.bbio
   fi
   # Detect A/B PIN with P8_16
   pin='46'
   if [ ! -d /sys/class/gpio/gpio$pin ]; then
      echo $pin > /sys/class/gpio/export
      wait_writeable "$pin"
   fi
   echo in > /sys/class/gpio/gpio$pin/direction
   REV=$(cat /sys/class/gpio/gpio$pin/value)
   if [ "$REV" == "0" ]; then
      echo Rev B Board
   else
      echo Rev A Board
   fi
   # 30 track0(B), 31 drive1 select/recovery, 51 write fault(C)
   # 60 emulation xcvr en
   # 61 testing(B)
   pins_low="30 31 51 60"
   # 14,15(B) drive selected LEDS
   # 50 mfm read xcvr en
   pins_high="14 15 50"
fi


# With univeresal cape header, all pins are exported and set to in by default.
# However, we now support reboot-less operation, so set them all anyway.
if [ "$KERNEL_VER" -lt "4" ]; then
   # 2-5, 22,23,26,27 Drive select and head select
   pins_in="2 3 4 5 22 23 26 27 8 9 10 11"
else
   pins_in="22 23 26 27"
fi
for pin in $pins_in $pins_low $pins_high; do
  if [ ! -d /sys/class/gpio/gpio$pin ]; then
     echo $pin > /sys/class/gpio/export
  fi
   wait_writeable "$pin"
   echo in > /sys/class/gpio/gpio$pin/direction
done

for pin in $pins_low; do
   echo out > /sys/class/gpio/gpio$pin/direction
   echo 0 > /sys/class/gpio/gpio$pin/value
done

for pin in $pins_high; do
   echo out > /sys/class/gpio/gpio$pin/direction
   echo 1 > /sys/class/gpio/gpio$pin/value
done

# hide dmesg warnings about unhandled IRQs
# (IRQs are being handled by the PRUs directly, not Linux)
if [ "$KERNEL_VER" -ge "4" ]; then
   gpiomon gpiochip0 8 9 10 11 12 13 > /dev/null 2>&1 &
   sleep 0.5
   kill $!
fi
