#!/bin/bash ### BEGIN INIT INFO # Provides: mts-io # Default-Start: S # Default-Stop: # Short-Description: load the mts-io driver # Description: mts-io driver initializes the Conduit hardware and # provides user mode access through the driver to the # Conduit features. ### END INIT INFO . /etc/default/mts-io i2c=/sys/bus/i2c/devices/ GPSCONFIGTYPE="/var/run/config/gpstype" HWPATH="/sys/devices/platform/mts-io/hw-version" MTSIOMODPATH="/lib/modules/$(uname -r)/extra/" MTCDTBB="${MTSIOMODPATH}/mtcdt3b.ko" ((fail=0)) # To log debug, set LOGDBG to /usr/bin/LOGGER if ((DEBUG)) ; then LOGDBG=/usr/bin/logger ${LOGDBG} -t "mts-io" -p daemon.info -s "LOGDBG turned on" else LOGDBG=":" fi hw="" hw_name="" MTAC_MODULES="" ((HASAP=0)) remove_mod() { mod=$1 # modprobe -R does not work for modules not in /lib/modules if lsmod | grep -E "^${mod}[[:space:]]" ; then if ! modprobe -r ${mod} ; then rmmod ${mod} fi fi } sethwtype() { # mts-io must be loaded before trying this # Also, mtcdt3b should be loaded if it exists hw=$(${SYSFS} show hw-version) hw_name=(${hw//-/ }) # Only MTCDT and MTCDTIP have accessory cards, and # MTCDTIPHP does not have accessory cards. ((HASAP==0)) case $hw_name in MTCDTIPHP) ;; MTCDT|MTCDTIP|MTCDT3|MTCDT3AC) if [[ $hw =~ MTCDT3-LORA16-0.0 ]] ; then return 0 fi ((HASAP = 1)) ;; *) ;; esac MTAC_MODULES=$(cd ${MTSIOMODPATH};ls mtac_* 2>/dev/null) MTBB_MODULES=$(cd ${MTSIOMODPATH};ls mtcdt3b_* 2>/dev/null) } SYSFS="/usr/sbin/mts-io-sysfs" LRST="/usr/sbin/mts-util-lora2-reset" ${LOGDBG} -p daemon.info 'mts-io script' sysdir=/sys/devices/platform/mts-io gpiodir=/sys/class/gpio port1=${sysdir}/ap1 port2=${sysdir}/ap2 USBRST=${sysdir}/usbhub-reset NEED_I2C_RESET=0 HWVER="" HWNAME="" HWLVL="" # WIFIBTRESET is used later, so it must match # the index of the RST variable for wifi-bt-reset. WIFIBTRESET=0 RST[${WIFIBTRESET}]="${sysdir}/wifi-bt-reset" RST[1]="${sysdir}/mtq-reset" RST[2]="${sysdir}/ap1/reset" RST[3]="${sysdir}/ap1/creset" RST[4]="${sysdir}/ap2/reset" RST[5]="${sysdir}/ap2/creset" RST[6]="${sysdir}/secure-reset" RST[7]="${sysdir}/eth-reset" RST[8]="${sysdir}/sm1-reset" RST[9]="${sysdir}/slot1/reset" RST[10]="${sysdir}/slot1/creset" RST[11]="${sysdir}/slot2/reset" RST[12]="${sysdir}/slot2/creset" if ((GPSGNSSRESET)) ; then RST[13]="${sysdir}/gnss-reset" fi WPIN[0]="${sysdir}/ap1/cdone" WPIN[1]="${sysdir}/ap2/cdone" WPIN[2]="${sysdir}/slot1/cdone" WPIN[3]="${sysdir}/slot2/cdone" USLPTIME=60000 # 30 milliseconds from Redpine Signals Reset Spec WAIT="/bin/busybox usleep ${USLPTIME}" # Wait 10 WAIT intervals for pins to come high waitpins() { ((i=0)) while((i < ${#WPIN[@]})) ; do ((j=0)) while [[ -r ${WPIN[$i]} ]] && ! (($(cat ${WPIN[$i]}))) ; do logger -t "mts-io" -p daemon.error -s "Wait on ${WPIN[$i]}" ${WAIT} ((j++)) if ((j > 10)) ; then ((fail++)) ${LOGDBG} -t "mts-io" -p daemon.error -s "Ready failure on ${WPIN[$i]}" break fi done ((i++)) done } reset_path() { pin=$1 ${LOGDBG} -t "mts-io" -p daemon.info Reset $pin if [[ -f ${pin} ]] ; then if ! ( (echo 0 >${pin}) && ${WAIT} && (echo 1 >${pin}) ) ; then /usr/bin/logger -t "mts-io" -p daemon.error -s "Failed write to ${pin}" return 1 fi sleep 2 ${LOGDBG} -t "mts-io" -p daemon.info Completeed reset $pin else ${LOGDBG} -t "mts-io" -p daemon.info "${pin} does not exist" fi return 0 } reset_array() { ((i=${#RST[@]}-1)) while ((i>=0)) ; do if [[ -f ${RST[$i]} ]] ; then if ! ( (echo 1 >${RST[i]}) ) ; then /usr/bin/logger -t "mts-io" -p daemon.error -s "Failed write to ${RST[$i]}" fail=1 else ${LOGDBG} -t "mts-io" -p daemon.error -s "Wrote 1 to ${RST[$i]}" fi else ${LOGDBG} -t "mts-io" -p daemon.info "${RST[$i]} does not exist" RST[$i]="" fi ((i--)) done ((DBG)) && (cd $sysdir ; head gnss-reset eth-reset wifi-bt-reset usbhub-reset | logger -p daemon.info) ((i=${#RST[@]}-1)) while ((i>=0)) ; do ${LOGDBG} -s -p daemon.info "i value is $i RST is ${RST[$i]} count is ${#RST[$i]}" if ((${#RST[$i]} > 0)) && [[ -f ${RST[$i]} ]] ; then if ! ( (echo 0 >${RST[i]}) ) ; then /usr/bin/logger -t "mts-io" -p daemon.error -s "Failed write to ${RST[$i]}" fail=1 else ${LOGDBG} -t "mts-io" -p daemon.error -s "Wrote 0 to ${RST[$i]}" : fi else ${LOGDBG} -t "mts-io" -p daemon.info "${RST[$i]} does not exist" fi ((i--)) done ${WAIT} ((DBG)) && (cd $sysdir ; head gnss-reset eth-reset wifi-bt-reset usbhub-reset | logger -p daemon.info) ((i=${#RST[@]}-1)) while ((i>=0)) ; do if ((${#RST[$i]} > 0)) && [[ -f ${RST[$i]} ]] ; then if ! ( (echo 1 >${RST[$i]}) ) ; then /usr/bin/logger -t "mts-io" -p daemon.error -s "Failed write to ${RST[$i]}" fail=1 else ${LOGDBG} -t "mts-io" -p daemon.error -s "Wrote 1 to ${RST[$i]}" fi else ${LOGDBG} -t "mts-io" -p daemon.info "${RST[$i]} does not exist" fi ((i--)) done ((DBG)) && (cd $sysdir ; head gnss-reset eth-reset wifi-bt-reset usbhub-reset | logger -p daemon.info) return $fail } read_card_info() { ap1_product_id="" ap2_product_id="" if [[ -d $sysdir/ap1 ]]; then ap1_product_id=$(cat $sysdir/ap1/product-id) fi if [[ -d $sysdir/ap2 ]]; then ap2_product_id=$(cat $sysdir/ap2/product-id) fi lora_hw=$(${SYSFS} show lora/hw-version 2> /dev/null) if [[ $hw_name == MTCDT3 || $hw_name == MTCDT3AC ]] ; then # spidev module is not needed in MTCDT3. return 0 fi if [[ ${hw_name} == MTCAP ]] || [[ ${hw_name} == MTCDT ]] || [[ ${hw_name} == MTCDTIP ]]; then modprobe spidev elif [[ ${hw_name} == MTCDTIPHP ]]; then modprobe spidev fi } mfser_init() { found_ap1=0 if [[ $ap1_product_id =~ ^MTAC-MFSER- ]]; then /usr/bin/logger -t "mts-io" -p daemon.info -s "Linking /dev/mfser to /dev/ttyAP1" ln -sf /dev/ttyAP1 /dev/mfser found_ap1=1 fi if [[ $ap2_product_id =~ ^MTAC-MFSER- ]]; then if [[ $found_ap1 = 1 ]]; then /usr/bin/logger -t "mts-io" -p daemon.info -s "Linking /dev/mfser-2 to /dev/ttyAP2" ln -sf /dev/ttyAP2 /dev/mfser-2 else /usr/bin/logger -t "mts-io" -p daemon.info -s "Linking /dev/mfser to /dev/ttyAP2" ln -sf /dev/ttyAP2 /dev/mfser fi fi } set_links() { [[ -d /var/run/config ]] || mkdir /var/run/config gpscap=$(cat ${sysdir}/capability/gps) # Oldest MTRV1 uses venus on ttyS1. # Newest MTRV1 usus U-Blox on ttyS1. if [[ ${hw_name} == MTRV1 ]] ; then case "${hw}" in MTRV1-0.0) if ((gpscap == 1)) ; then ln -sf /dev/ttyS1 /dev/gps0 echo "venus" >"$GPSCONFIGTYPE" fi return ;; MTRV1-0.1|MTRV1-0.2|MTRV1-0.3) if ((gpscap == 1)) ; then ln -sf /dev/ttyXRUSB0 /dev/gps0 echo "u-blox" >"$GPSCONFIGTYPE" fi return ;; *) if ((gpscap == 1)) ; then ln -sf /dev/ttyS1 /dev/gps0 echo "u-blox" >"$GPSCONFIGTYPE" fi ln -sf /dev/ttyS4 /dev/ext_serial return ;; esac fi # MTRV1 hardware version name # Continue with non-MTRV1 hardware. # For all other hardware except MTCDTIPHP, the gpscapability # flag indicates whether or not we have a GPS. if ! [[ ${hw_name} =~ ^MTCDTIPHP$ ]] && ((gpscap == 0)) ; then return fi case ${hw_name} in MTR|MTHS) ln -sf /dev/ttyS1 /dev/gps0 echo "venus" >"$GPSCONFIGTYPE" return ;; MTCDT3|MTCDT3AC) cpuhw=$(mts-io-sysfs show cpu/hw-version) case ${cpuhw} in MTCPM-0.0) ln -sf /dev/ttyS1 /dev/gps0 ;; MTCPM-0.1) ln -sf /dev/ttyACM0 /dev/gps0 ;; MTCPM-0.2) ln -sf /dev/ttyS4 /dev/gps0 ;; esac echo "u-blox" >"$GPSCONFIGTYPE" return ;; esac # not MTRV1 hardware version names if [[ ${hw} == MTCDT ]] && [[ ${HWLVL} == 0.0 ]] ; then # No GPS return fi if [[ ${hw_name} == MTCDTIPHP ]] ; then NEED_I2C_RESET=1 ln -sf /dev/ttyXRUSB0 /dev/gps0 return fi # Default MTCDT-0.1 echo "u-blox" >"$GPSCONFIGTYPE" # Link up GPS for MTCDT and MTCDTIP in udev } case $1 in start) # Point the firmware API at our i2c EEPROMs echo -n ${i2c} > /sys/module/firmware_class/parameters/path /usr/bin/logger -t "mts-io" -p daemon.info -s "Loading mts-io module" if ! modprobe mts_io "$MTS_IO_PARAMS" ; then ((fail++)) fi # MTCDTBB driver is needed to determine the product type on MTCDT3 if [[ -f ${MTCDTBB} ]] ; then if ! modprobe mtcdt3b ; then ((fail++)) fi fi sethwtype if ((HASAP == 1)) ; then # install mtac explicitly or any unused modules will cause # junk to the log as mtac is loaded and unloaded each time. modprobe mtac for f in ${MTAC_MODULES} ; do modprobe ${f//.ko} 2>&1 | grep -v 'No such device or address' done fi if ((${#MTBB_MODULES})) ; then # install mcdt3b explicitly or any unused modules will cause # junk to the log as mtcdt3b is loaded and unloaded each time. modprobe mtcdt3b for f in ${MTBB_MODULES} ; do modprobe ${f//.ko} 2>&1 | grep -v 'No such device or address' done fi set_links # Set GPS symlink and maybe external serial. /usr/bin/logger -t "mts-io" -p daemon.info -s "Resetting system modules" read_card_info /bin/busybox usleep $USLPTIME # MTCDT-0.2 has issues with resetting RS9113 twice. # RS9113 is reset in /etc/init.d/rs9113. # Remove for MTRV1 reset as well, as it is redundant. if [[ $hw_name == MTCDT ]] || [[ $hw_name == MTRV1 ]] || [[ $hw_name == MTCDTIP ]] ; then RST[${WIFIBTRESET}]="/dev/null" fi reset_array # use radio-reset init script for radio-reset mfser_init waitpins # Fix Telit error -62 and Redpine wrong USB speed detection on reset. sleep 1 # Turn on radio-udev-discovery mts-io-sysfs store radio-udev-discovery 5 if ! reset_path $USBRST ; then ((fail++)) fi if ((${#lora_hw} > 0)) && [[ ${lora_hw} =~ ^MTCDTIPHP-LORA-2\.1 ]] ; then if [[ -x ${LRST} ]] ; then ${LRST} -g -f else /usr/bin/logger -t "mts-io" -p daemon.err -s "ERROR: Missing ${LRST} -- Cannot initialize LoRa." fi fi if [[ -d ${DEVTREE} ]] ; then /bin/umount configfs fi if ((fail == 0)) ; then echo "OK" else echo "FAIL" fi exit $fail ;; stop) # Remove modules that fall down when # mts-io is removed. remove_mod rsi_sdio remove_mod wlcore_sdio remove_mod wl18xx remove_mod wlcore if [[ -x /usr/sbin/rs9113_remove_modules.sh ]] ; then /usr/sbin/rs9113_remove_modules.sh else remove_mod mac80211 remove_mod cfg80211 remove_mod bluetooth fi /usr/bin/logger -t "mts-io" -p daemon.info -s "Unloading mtac modules and mts-io module" MTAC_MODULES=$(lsmod | grep '^mtac_' | sed -e 's/_/-/' -e 's/ .*//') MTCDT3B_MODULES=$(lsmod | grep '^mtcdt3b_' | sed -e 's/_/-/' -e 's/ .*//') for f in ${MTAC_MODULES} ; do remove_mod "$f" done remove_mod mtac remove_mod mtcdt3b remove_mod mts_io RETVAL=$? if ((RETVAL == 0)) ; then echo "OK" else echo "FAIL" fi ;; restart) $0 stop sleep 1 $0 start ;; reload) /usr/bin/logger -t "mts-io" -p daemon.info -s "Resetting system modules" if ! reset_path $USBRST ; then ((fail++)) fi /bin/busybox usleep $USLPTIME reset_array # Use radio-reset init script for radio-reset mfser_init if ((fail == 0)) ; then echo "OK" else echo "FAIL" fi exit $fail ;; status) if [[ -d ${sysdir} ]] ; then echo Driver is loaded exit 0 else echo Driver is not loaded exit 3 fi ;; *) echo "Usage: $0 {start|stop|status|restart}" exit 2 ;; esac