#!/bin/sh
###
#       Enable GPIO for GWM VMX53
##

. /usr/local/bin/telem/functions
. /usr/local/bin/telem/modem_functions

GPIO=/usr/local/bin/telem/gpio.sh

GPIOPATH='/usr/local/etc/telem/hwdata/gpio/UNK.0'
REVPATH='/usr/local/etc/telem/hwdata/rev/UNK.0'

minRev=1

ethboard() {
    # set revision variable if not set (mostly for stop option)
    : ${revision:=$(cat '/tmp/telem/board/rev')}
    # test conditions
    test -e '/var/local/telem/ordercode/eth_board' && \
    (test -e '/etc/init.d/network_eth1' || test -e '/etc/init.d/network_eth2' || test -e '/etc/init.d/network_eth3')
}

ioboard() {
    test -e '/var/local/telem/ordercode/io_board'
}

COM4() {
    [ "SLC" = "${base}" ] && return 1
    test -e '/var/local/telem/ordercode/com4'
}

COM4x2() {
    [ "SLC" = "${base}" ] && return 1
    test -e '/var/local/telem/ordercode/com4x2'
}

updateVars() {
    revName="${boardname}.${base}${revision:-1}"
    GPIOPATH="/usr/local/etc/telem/hwdata/gpio/$revName"
    REVPATH="/usr/local/etc/telem/hwdata/rev/$revName"
}

linkf() {
    # $1: source path
    # $2: target path
    rm "$2" &> /dev/null
    ln -sf "$1" "$2"
}

setAGW_minRev() {
    read minRev < '/sys/firmware/devicetree/base/info/rev-min'
    : ${minRev:=1}
    revision="${minRev}"
}

setAny_gpioRevUnknown() {
    defrev="${1:-1}"
    loggwarn "Unknown revision bits 0b${rev_bits}, default to rev${defrev}"
    revision="${defrev}"
}

setAGW1p_gpioRev() {
    # AGW rev1 plus newer
    $GPIO -e REV_BIT0
    $GPIO -e REV_BIT1
    $GPIO -e REV_BIT2
    $GPIO -e REV_BIT3

    rev_bits="$($GPIO -v REV_BIT0)$($GPIO -v REV_BIT1)$($GPIO -v REV_BIT2)$($GPIO -v REV_BIT3)"
    case ${rev_bits} in
        1111) revision=1
        ;;
        0111) revision=2
        ;;
        1011) revision=5
        ;;
        0011) revision=6
        ;;
        *)    setAny_gpioRevUnknown 5
        ;;
    esac
}

setSLC_minRev() {
    # rev1 and rev3 differences are not detectable from hw,
    # so we need to trust device tree
    read minRev < '/sys/firmware/devicetree/base/info/rev-min'
    # rev2 has i2c ds2482@18 and ds1339@68, but we can detect this from rev1 bits
    # TODO: set rev3 by default
    : ${minRev:=1}
    revision="${minRev}"
}

setSLC1p_gpioRev() {
    # SLC rev1 plus newer
    $GPIO -e REV_BIT0
    $GPIO -e REV_BIT1
    $GPIO -e REV_BIT2
    # we could just ignore bit3, as only rev1 and rev2 had four bits
    $GPIO -e REV_BIT3

    rev_bits="$($GPIO -v REV_BIT0)$($GPIO -v REV_BIT1)$($GPIO -v REV_BIT2)$($GPIO -v REV_BIT3)"
    case ${rev_bits} in
        1111) revision=1
        ;;
        0111) revision=2
        ;;
        1011) revision=5
        ;;
        0011) revision=8
        ;;
        *)    setAny_gpioRevUnknown 8
        ;;
    esac
}

setSLC2p_gpioRev() { setSLC1p_gpioRev; }
setSLC5p_gpioRev() { setSLC1p_gpioRev; }
setSLC8p_gpioRev() { setSLC1p_gpioRev; }

setSLC3p_gpioRev() {
    # SLC rev3 plus newer
    $GPIO -e REV_BIT0
    $GPIO -e REV_BIT1
    $GPIO -e REV_BIT2

    rev_bits="$($GPIO -v REV_BIT0)$($GPIO -v REV_BIT1)$($GPIO -v REV_BIT2)"
    case ${rev_bits} in
        111) revision=3
        ;;
        *)   setAny_gpioRevUnknown 3
        ;;
    esac
}

setSFP_minRev() {
    read minRev < '/sys/firmware/devicetree/base/info/rev-min'
    : ${minRev:=1}
    revision="${minRev}"
}

setSFP2p_gpioRev() {
    # SFP rev2 plus newer
    $GPIO -e REV_BIT0
    $GPIO -e REV_BIT1
    $GPIO -e REV_BIT2
    $GPIO -e REV_BIT3

    rev_bits="$($GPIO -v REV_BIT0)$($GPIO -v REV_BIT1)$($GPIO -v REV_BIT2)$($GPIO -v REV_BIT3)"
    case ${rev_bits} in
        0011) revision=2
        ;;
        1101) revision=3
        ;;
        0101) revision=4
        ;;
        *)    setAny_gpioRevUnknown 2
        ;;
    esac
}

setSFP1p_gpioRev() { setSFP2p_gpioRev; }
setSFP3p_gpioRev() { setSFP2p_gpioRev; }
setSFP4p_gpioRev() { setSFP2p_gpioRev; }

hwsetup() {
    if [ -r '/usr/local/etc/telem/hw/gwhw.conf' ]; then
        . '/usr/local/etc/telem/hw/gwhw.conf'
    fi
    ln -sf "${MAIN_I2C:-/dev/i2c-0}" /dev/i2c-main
}

detectHW() {
    boardname="$(/usr/local/bin/telem/boardname.sh)"

    # AGC SLC rev1+ has pca9554 at 0x20 on i2c-2
    grep -Fq -- 'pca9554@20' /sys/class/gpio/gpiochip504/device/uevent 2>/dev/null \
    && base='SLC'

    # AGC SLC rev1 PROTOTYPE has pca9554 at 0x22 on i2c-2
    # TODO remove
    grep -Fq -- 'pca9554@22' /sys/class/gpio/gpiochip504/device/uevent 2>/dev/null \
    && base='SLC'

    # AGC AGW rev1+ has pca9536 at 0x41 on i2c-2
    grep -Fq -- 'pca9536@41' /sys/class/gpio/gpiochip508/device/uevent 2>/dev/null \
    && base='AGW'

    # AGC SFP rev2+
    # gpiochip500 can be one of pca9536@41 or pca9554@38 if powered late.
    grep -q -- 'pca9536@41\|pca9554@38' /sys/class/gpio/gpiochip500/device/uevent 2>/dev/null \
    && base='SFP'

    "set${base}_minRev"

    updateVars
    linkf "$GPIOPATH" '/usr/local/etc/telem/gpio'
    linkf "$REVPATH"  '/usr/local/etc/telem/hw'

    "set${base}${minRev}p_gpioRev"

    updateVars
    linkf "$GPIOPATH" '/usr/local/etc/telem/gpio'
    linkf "$REVPATH"  '/usr/local/etc/telem/hw'

    if COM4x2; then
        linkf "$REVPATH/hw-com4x2.xml" '/usr/local/etc/telem/hw-run.xml'
    elif COM4; then
        linkf "$REVPATH/hw-com4.xml"   '/usr/local/etc/telem/hw-run.xml'
    else
        linkf "$REVPATH/hw.xml"        '/usr/local/etc/telem/hw-run.xml'
    fi
    
    hwsetup

    mkdir -p '/tmp/telem/board'
    echo "$boardname" > '/tmp/telem/board/board'
    echo "$revision"  > '/tmp/telem/board/rev'
}

resetSFPeth() {
    # $1: line name
    line="$(gpiofind "$1")"
    [ -z "${line}" ] && return
    gpioset -m time -u 100000 ${line}=0
    gpioset ${line}=1
}

setSFPeth() {
    # $1: line name
    line="$(gpiofind "$1")"
    [ -z "${line}" ] && return
    gpioset ${line}=1
}

start() {
    logg "Initializing GPIOs"

    # remove unused
    rm -r "/usr/local/etc/telem/gpio.2"        2> /dev/null
    rm -r "/usr/local/etc/telem/"TX6[UD]L.[49] 2> /dev/null
    rm -r "/usr/local/etc/telem/"VMX25.[2489]  2> /dev/null
    rm -r "/usr/local/etc/telem/"VMX53.[1489]  2> /dev/null

    detectHW

    $GPIO -e RUN_LED
    $GPIO -e ALERT_LED

    if [ "$base" = 'SLC' ]; then
        $GPIO -e IO_BOARD_PWR
    fi

    modemInstalled && modemConfigured && {
        if [ "$base" = 'AGW' ] || [ "$base" = 'SFP' ]; then
            $GPIO -e MODEM_SIM1
            $GPIO -e MODEM_SIM2
            $GPIO -e MODEM_SIM_SELECT
        fi
        $GPIO -e RST_MODEM
        $GPIO -e MODEM_PWR
    }

    if [ "$base$revision" = 'AGW1' ]; then
        # AGW rev1 eth1 share power with modem
        $GPIO -es MODEM_PWR
    fi

    # PERIF_USB_PWR is for LAN board, gwmio, and other extra boards.
    # TODO: turn it on when actually needed
    $GPIO -es PERIF_USB_PWR

    if [ "$base" = 'SFP' ]; then
        setSFPeth 'RST-LANA' &
        setSFPeth 'RST-LANB' &
    fi
}


stop() {
    $GPIO -c RUN_LED
    $GPIO -s ALERT_LED

    modemInstalled && modemConfigured && modem_turnOFF
    ethboard && $GPIO -c PERIF_USB_PWR
}


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

esac

exit $?
