#!/bin/bash
#
# SPDX-License-Identifier: Apache-2.0
#
# Authors:
#        2024        Elvis Yao        <ElvisCW.Yao@moxa.com>
#        2024        Henry LC Chen     <HenryLC.Chen@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="2"
        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~7 default mode as RS-232 for Expansion Card
        if [ -e "/dev/ttyM2" ]; then
                ${UARTPROG} -p 2 -m 0
                ${UARTPROG} -p 3 -m 0
                ${UARTPROG} -p 4 -m 0
                ${UARTPROG} -p 5 -m 0
                ${UARTPROG} -p 6 -m 0
                ${UARTPROG} -p 7 -m 0
                ${UARTPROG} -p 8 -m 0
                ${UARTPROG} -p 9 -m 0
        fi
}

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
}

function get_i2c_device_minor_number_list() {
        local i2c_device_name=$1
        local i2c_num=0
        local i2c_nums=()

        for filename in /sys/bus/i2c/devices/i2c-*/name; do
                i2c_devname=$(cat "${filename}")
                if [[ $i2c_devname == *"$i2c_device_name"* ]]; then
                        i2c_devpath="${filename%/*}"
                        i2c_num=$(echo "${i2c_devpath}" | cut -d '-' -f2)
                        i2c_nums+=("$i2c_num")
                fi
        done

        echo "${i2c_nums[@]}"
}

bind_lm75() {
        local soc_i2c_num_str
        local soc_i2c_num_array
        local soc_i2c_num_on_lm75
        local i2c_devpath

        soc_i2c_num_str=$(get_i2c_device_minor_number_list "Synopsys DesignWare I2C adapter")
        IFS=" " read -r -a soc_i2c_num_array <<<"$soc_i2c_num_str"
        soc_i2c_num_on_lm75=${soc_i2c_num_array[2]}
        i2c_devpath="/sys/bus/i2c/devices/i2c-$soc_i2c_num_on_lm75"

        echo "lm75 0x48" >"${i2c_devpath}"/new_device
        echo "lm75 0x49" >"${i2c_devpath}"/new_device
}

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

        # bind LM75 for power temperature detect
        bind_lm75
}

main
