# initscript to check that the HSIC hub (if fitted) is functioning.
# If it has not initialised correctly, a re-enumeration mechanism is invoked.

PATH=/bin:/sbin:/usr/bin:/usr/sbin

set -e

HWPROBE_PATH=/sys/devices/soc0/hdl-hw-probe
HSIC_DET_PATH=${HWPROBE_PATH}/det_hsic
USB_OTG1_DET_PATH=${HWPROBE_PATH}/det_usb_otg1
if [ "$(cat ${USB_OTG1_DET_PATH} 2>/dev/null)" = "present" ]; then
    HUB_PATH=/sys/devices/soc0/soc/30800000.aips-bus/30b30000.usb/ci_hdrc.1/usb2/2-1
else
    HUB_PATH=/sys/devices/soc0/soc/30800000.aips-bus/30b30000.usb/ci_hdrc.0/usb1/1-1
fi

FG_PRESENCE_TIMEOUT=2
BG_PRESENCE_TIMEOUT=3
BG_MAX_CNT=10
BG_INTER_RETRY_SLEEP=1

function hsic_check() {
    local VID="$(cat $HUB_PATH/idVendor 2>/dev/null || true)"
    local PID="$(cat $HUB_PATH/idProduct 2>/dev/null || true)"
    test "$VID" = "0424" -a "$PID" = "3503"
}

# $1 - timeout (seconds)
function hsic_check_wait() {
    TO=$(( $1 * 5 ))
    while ! hsic_check ; do
        if [ $TO -eq 0 ]; then
            return 1
        fi
        sleep 0.2
        TO=$(( TO - 1 ))
    done
    return 0
}

function hsic_reenum() {
    modprobe -r usb3503
    echo disabled >/sys/devices/soc0/hdl-hw-probe/switch_usbh
    echo enabled >/sys/devices/soc0/hdl-hw-probe/switch_usbh
    modprobe usb3503
}

function run_background() {
    if hsic_check_wait $(( BG_PRESENCE_TIMEOUT - FG_PRESENCE_TIMEOUT )) ; then
        echo "HSIC hub: re-enumeration successful"
        return 0
    fi

    CNT=$BG_MAX_CNT
    while [ $CNT -ne 0 ] ; do
        hsic_reenum
        if hsic_check_wait $BG_PRESENCE_TIMEOUT ; then
            echo "HSIC hub: re-enumeration successful"
            return 0
        fi
        sleep $BG_INTER_RETRY_SLEEP
        CNT=$(( CNT - 1 ))
    done
    echo "HSIC hub: failed to re-enumerate. Giving up after $BG_MAX_CNT retries"
    return 1
}

function run_start() {
    echo -n "HSIC hub: Checking hub... "
    HSIC_DET="$(cat $HSIC_DET_PATH 2>/dev/null || true)"
    if [ "$HSIC_DET" != "present" ] ; then
        echo "not present"
        return 0
    fi
    if hsic_check ; then
        echo "present, functioning"
        return 0
    fi
    echo "present, not functioning. Re-enumerating..."
    hsic_reenum
    if hsic_check_wait $FG_PRESENCE_TIMEOUT ; then
        echo "HSIC hub: re-enumeration successful"
        return 0
    fi
    echo "HSIC hub: re-enumeration timeout. Going to background..."
    run_background &
    return 0
}

case "$1" in
  start)
    run_start
    ;;
  stop)
    ;;
  *)
      echo "Usage: $0 {start|stop}"
      exit 1
    ;;
esac

exit 0
