#!/bin/bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Authors:
#        2024        Elvis Yao        <ElvisCW.Yao@moxa.com>
#

UARTPROG="/sbin/mx-uart-ctl"
MAX_FT260_RETRY=10

# workaround for FT260 cannot send i2c message when warm reboot
check_ft260_is_alive() {
        # check serial start from port 0
        local ex_card_serial_port="0"
        local ret_val="0"
        local pca953x_failed="0"

        for i in $(seq 1 $MAX_FT260_RETRY); do
                if [ -e "/dev/ttyM${ex_card_serial_port}" ]; then
                        ${UARTPROG} -p ${ex_card_serial_port} >/dev/null 2>&1
                        ret_val="${?}"
                else
                        return 0
                fi

                if [ "${ret_val}" != "0" ]; then
                        pca953x_failed="1"
                        echo "Unable to read pca953x register, try to recover" >/dev/console
                        echo "FT260 is broken, rebind USB host driver (retry: ${i}/${MAX_FT260_RETRY})" >/dev/console
                        # rebind root hub
                        rebind_root_hub
                        set_default_mode
                else
                        if [ "${pca953x_failed}" == "1" ]; then
                                echo "Read the pca953x register successfully" >/dev/console
                        fi
                        # check re-bind ok and return
                        return 0
                fi
        done
}

set_default_mode() {
        if [ ! -f "${UARTPROG}" ]; then
                echo "${UARTPROG} is not exists."
                exit 1
        fi

        # UART port 0~1 default mode as RS-232
        ${UARTPROG} -p 0 -m 0
        ${UARTPROG} -p 1 -m 0

        # UART port 2~11 default mode as RS-485-2W
        ${UARTPROG} -p 2 -m 1
        ${UARTPROG} -p 3 -m 1
        ${UARTPROG} -p 4 -m 1
        ${UARTPROG} -p 5 -m 1
        ${UARTPROG} -p 6 -m 1
        ${UARTPROG} -p 7 -m 1
        ${UARTPROG} -p 8 -m 1
        ${UARTPROG} -p 9 -m 1
        ${UARTPROG} -p 10 -m 1
        ${UARTPROG} -p 11 -m 1
}

rebind_root_hub() {
        echo -n "0000:00:14.0" | tee /sys/bus/pci/drivers/xhci_hcd/unbind
        sleep 3
        echo -n "0000:00:14.0" | tee /sys/bus/pci/drivers/xhci_hcd/bind
        sleep 3
}

main() {
        # FIXME workaround for solving FT4232 tx/rx can't receive issue
        rebind_root_hub

        # set default UART mode for all ports
        set_default_mode

        # check and recover the FT260 chip
        check_ft260_is_alive
}

main
