#!/bin/bash

# Definitions
CONFIG=/boot/firmware/config.txt
CONFIG_BACKUP=${CONFIG}.prev
NEW_CONFIG=$(mktemp --dry-run -p /tmp config.txt.XXX)
IOTG_RPI4_CONFIG=$(mktemp --dry-run -p /tmp iotg-rpi4_config.XXX)
IOTG_RPI4_PATTERN="iotg-rpi4"

declare -A PERIPHERAL_DEVS=(
		[TPM]=OFF
)

# POD_DET GPIOs and chip
POD_DET_GPIO_CHIP=2
POD_DET_GPIO_CHIP_DEVPATH=/dev/gpiochip${POD_DET_GPIO_CHIP}
declare -A POD_DET_GPIOS=(
		[a]="0 1 2"
		[b]="3 4 5"
		[c]="6 7 8"
		[d]="9 10 11"
)

declare -A DUAL_POD_DET_GPIOS=(
		[ab]="0 1 2 3 4 5"
		[cd]="6 7 8 9 10 11"
)

# Default IE module types
IE_DET_DEF="Empty"
IE_CONF_DEF="Keep"

# Array of detected IE modules
declare -A IE_DETECTED=(
		[a]=${IE_DET_DEF}
		[b]=${IE_DET_DEF}
		[c]=${IE_DET_DEF}
		[d]=${IE_DET_DEF}
)

declare -A DUAL_IE_DETECTED=(
		[ab]=${IE_DET_DEF}
		[cd]=${IE_DET_DEF}
)

# Array of user defined IE modules configuration
declare -A IE_CONFIG=(
		[a]=${IE_CONF_DEF}
		[b]=${IE_CONF_DEF}
		[c]=${IE_CONF_DEF}
		[d]=${IE_CONF_DEF}
)

declare -A DUAL_IE_CONFIG=(
		[ab]=${IE_CONF_DEF}
		[cd]=${IE_CONF_DEF}
)

declare -A DUAL_SLOT_MAP=(
		[a]="ab"
		[b]="ab"
		[c]="cd"
		[d]="cd"
)

declare -A SLOT_CONFIG=(
		[Detect]="Detect currently plugged module type"
		[Keep]="Keep current module configuration unchanged"
		[CAN]="Configure CAN interface"
		[RS232]="Configure RS232 interface"
		[RS485]="Configure RS485 interface"
		[IO]="Configure Digital I/O - dual slot"
		[Empty]="Skip module type configuration"
		[Deactivate]="Detect currently plugged module type but leave inactive"
)

# Slot names
declare -a IE_SLOT_LCASE=(
		"a"
		"b"
		"c"
		"d"
)
declare -a IE_SLOT_UCASE=(
		"A"
		"B"
		"C"
		"D"
)

declare -a BUDDY_SLOT_LCASE=(
		"b"
		"a"
		"d"
		"c"
)

declare -a DUAL_IE_SLOT_LCASE=(
		"ab"
		"cd"
)
declare -a DUAL_IE_SLOT_UCASE=(
		"AB"
		"CD"
)

#############################################################################
# int get_ie_type() - determines IE board type for a pod with a given index
# @slot - slot name a, b, c, d
# A detected IE type is set in the IE_DETECTED[] array
#############################################################################
function get_ie_type() {
	local slot=${1:-}
	[[ ! -z ${slot} ]] || return 1;
	[[ -c ${POD_DET_GPIO_CHIP_DEVPATH} ]] || return 1;
	# Determine GPIOs
	case ${slot} in
	"a" | "b" | "c" | "d")
		pod_det_gpios=${POD_DET_GPIOS[${slot}]}
		;;
	"ab" | "cd")
		pod_det_gpios=${DUAL_POD_DET_GPIOS[${slot}]}
		;;
	*)
		return 1;
		;;
	esac
	# Read GPIOs
	local ie_cfg=$(gpioget ${POD_DET_GPIO_CHIP} ${pod_det_gpios})

	# Determine IE type
	local ie_type="Undefined"
	case $ie_cfg in
	"0 0 0")
		ie_type="Empty"
		;;
	"0 0 1")
		ie_type="CAN"
		;;
	"0 1 0")
		ie_type="RS485"
		;;
	"0 1 1")
		ie_type="RS232"
		;;
	"1 0 0")
		ie_type="IO"
		dslot=${DUAL_SLOT_MAP[${slot}]}
		DUAL_IE_DETECTED[${dslot}]="IO"
		;;
	"1 1 0")
		ie_type="IO"
		dslot=${DUAL_SLOT_MAP[${slot}]}
		DUAL_IE_DETECTED[${slot}]="IO"
		;;
	"1 0 0 1 1 0")
		DUAL_IE_DETECTED[${slot}]="IO"
		return 0
		;;
	*)
		ie_type="Undefined"
		;;
	esac
	IE_DETECTED[${slot}]=${ie_type}
	return 0
}

function get_ie_type_all() {
	local slot

	# Get all single slots types
	for slot in ${IE_SLOT_LCASE[@]}
	do
		get_ie_type $slot
	done

	# Get all dual slots types
	for slot in ${DUAL_IE_SLOT_LCASE[@]}
	do
		get_ie_type $slot
	done
}
