OpenWrt Forum Archive

Topic: How to disable hardware UART on ath79 devices

The content of this topic has been archived on 7 May 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

If suddenly it happens that you need to free GPIOs on UART(Serial Tx and Rx pins), then this topic is for you.

The fact that on processors AR71xx/AR913x/AR724X/AR933X - UART is locked by default and use internal resources (buffer, interrupt) for interaction with the kernel driver.
Therefore, when we trying to use these GPIOs(tx and rx) via sysfs - it fails.

So, it is possible to disable the internal UART via simple script (without the need to patch / recompile firmware):

Install io via opkg:

opkg update && opkg install io

If we use console, create empty file(or use sftp, scp, WinSCP):

touch /usr/sbin/uart_gpio

Script itself (copy this code into empty file):

#!/bin/sh
# Bitwise operations: & = And, | = Or, ^ = xOr, << = Left Shift

detect_addr="0x18060090"
rev_id_maj_msk="0xfff0"
func_addr="0x18040028"
bit1="1<<1"            # using bit1 for AR724x/AR933x
bit8="1<<8"            # using bit8 for AR71xx/AR913x

detect_value=0x`io -4 $detect_addr | cut -f3 -d' '`
detected_result=$(printf "0x%4.4x" $(($detect_value & $rev_id_maj_msk)))
func_value=0x`io -4 $func_addr | cut -f3 -d' '`

# depending on the detected rev_id of CPU -
# it will be use specific bit# as case_bit variable, or exit
case "$detected_result" in
# AR7240/AR7241/AR7242/AR9330/AR9331
0x00c0 | \
0x0100 | \
0x1100 | \
0x0110 | \
0x1110 )
    case_bit=$bit1
    ;;
# AR71xx/AR913x
0x00a0 | \
0x00b0 )
    case_bit=$bit8
    ;;
# AR9341/AR9342/AR9344
0x0120 | \
0x1120 | \
0x2120 )
    echo -e "No need to disable UART on AR934x processors,\n \
    just use sysfs to reprogram GPIOs."
    break
    exit 0
    ;;
* )
    echo "Can't detect your CPU, must be Atheros!"
    break
    exit 1
    ;;
esac

# we using Bitwise xOr operation to switching bit# state (0 or 1)
io -4 $func_addr $(printf "0x%8.8x" $(($func_value ^ $case_bit)))

# read bit# state and depending on the state - print some info
if [ $(($func_value & $case_bit)) = $(($case_bit)) ]; then
    echo "Hardware UART is turned OFF"
    # You can use this line for automatic configuring GPIOs via sysfs
    # or you can load other modules that use these GPIOs
else
    echo "Hardware UART is turned ON"
fi

Rights to execute the script:

chmod +x /usr/sbin/uart_gpio

Execute uart_gpio, or use /etc/rc.local for autoexecute.
(if we re-execute uart_gpio this will turn ON the HW-UART)

Source.

(UPDATE: cutted code in script - No need to unbind serial driver!)

(Last edited by Dioptimizer on 6 Jan 2014, 21:44)

The discussion might have continued from here.