#!/system/bin/sh
PATH=/sbin:/system/sbin:/system/bin:/system/xbin
export PATH
while getopts d op;
do
case $op in
d) dbg_on=1;;
esac
done
shift $(($OPTIND-1))
scriptname=${0##*/}
uppers=ABCDEFP1234567890
lowers=abcdefp1234567p9
convert_to_pnotation()
{
result=""
let i=0
while ([ $i -lt ${#1} ]) do
sym=${1:$i:1}
case $uppers in
*$sym*) sym=${uppers%$sym*}; result="${result}${lowers:${#sym}:1}";;
*) result="${result}$sym";;
esac
i=$((i + 1))
done
echo "$result"
unset i result
}
debug()
{
[ $dbg_on ] && echo "Debug: $*"
}
notice()
{
echo "$*"
echo "$scriptname: $*" > /dev/kmsg
}
error_and_leave()
{
local err_msg
local err_code=$1
case $err_code in
1) err_msg="Error: No response from touch IC";;
2) err_msg="Error: Cannot read property $1";;
3) err_msg="Error: No matching firmware file found";;
4) err_msg="Error: Touch IC is in bootloader mode";;
5) err_msg="Error: Touch provides no reflash interface";;
6) err_msg="Error: Touch driver is not running";;
esac
notice "$err_msg"
exit $err_code
}
for touch_vendor in $*; do
debug "searching driver for vendor [$touch_vendor]"
touch_driver_link=$(ls -l /sys/bus/i2c/drivers/$touch_vendor*/*-*)
if [ -z "$touch_driver_link" ]; then
debug "no driver for vendor [$touch_vendor] is running"
shift 1
else
debug "driver for vendor [$touch_vendor] found!!!"
break
fi
done
[ -z "$touch_driver_link" ] && error_and_leave 6
touch_path=/sys/devices/${touch_driver_link#*devices/}
debug "sysfs touch path: $touch_path"
[ -f $touch_path/doreflash ] || error_and_leave 5
[ -f $touch_path/poweron ] || error_and_leave 5
debug "wait until driver reports <ready to flash>..."
while true; do
readiness=$(cat $touch_path/poweron)
if [ "$readiness" == "1" ]; then
debug "ready to flash!!!"
break;
fi
sleep 1
debug "not ready; keep waiting..."
done
unset readiness
device_property=ro.boot.device
hwrev_property=ro.boot.hwrev
firmware_path=/system/vendor/firmware
let dec_cfg_id_boot=0; dec_cfg_id_latest=0;
read_touch_property()
{
property=""
debug "retrieving property: [$touch_path/$1]"
property=$(cat $touch_path/$1 2> /dev/null)
debug "touch property [$1] is: [$property]"
[ -z "$property" ] && return 1
return 0
}
find_latest_config_id()
{
debug "scanning dir for files matching [$1]"
str_cfg_id_latest=""
let dec=0; max=0;
for file in $(ls $1 2>/dev/null);
do
x=${file#*-}; z=${x#*-}; str_hex=${z%%-*};
let dec=0x$str_hex
if [ $dec -gt $max ];
then
let max=$dec; dec_cfg_id_latest=$dec;
str_cfg_id_latest=$str_hex
fi
done
unset dec max x z str_hex
[ -z "$str_cfg_id_latest" ] && return 1
return 0
}
read_touch_property flashprog || error_and_leave 1
bl_mode=$property
debug "bl mode: $bl_mode"
read_touch_property productinfo || error_and_leave 1
touch_product_id=$property
if [ -z "$touch_product_id" ] || [ "$touch_product_id" == "0" ];
then
debug "touch ic reports invalid product id"
error_and_leave 3
fi
debug "touch product id: $touch_product_id"
read_touch_property buildid || error_and_leave 1
str_cfg_id_boot=${property#*-}
let dec_cfg_id_boot=0x$str_cfg_id_boot
debug "touch config id: $str_cfg_id_boot"
product_id=$(getprop $device_property 2> /dev/null)
[ -z "$product_id" ] && error_and_leave 2 $device_property
product_id=${product_id%-*}
debug "product id: $product_id"
hwrev_id=$(getprop $hwrev_property 2> /dev/null)
[ -z "$hwrev_id" ] && error_and_leave 2 $hwrev_property
hwrev_id=${hwrev_id#*x}
hwrev_id=$(convert_to_pnotation $hwrev_id)
debug "hw revision: $hwrev_id"
cd $firmware_path
debug "search for best hw revision match"
hw_mask="-$hwrev_id"
while [ ! -z "$hw_mask" ]; do
if [ "$hw_mask" == "-" ]; then
hw_mask=""
fi
find_latest_config_id "$touch_vendor-$touch_product_id-*-$product_id$hw_mask.*"
if [ $? -eq 0 ]; then
break;
fi
hw_mask=${hw_mask%?}
done
[ -z "$str_cfg_id_latest" ] && error_and_leave 3
firmware_file=$(ls $touch_vendor-$touch_product_id-$str_cfg_id_latest-*-$product_id$hw_mask.*)
debug "firmware file for upgrade $firmware_file"
if [ $dec_cfg_id_boot -ne $dec_cfg_id_latest ] || [ "$bl_mode" == "1" ];
then
debug "forcing firmware upgrade"
echo 1 > $touch_path/forcereflash
debug "sending reflash command"
echo $firmware_file > $touch_path/doreflash
read_touch_property flashprog || error_and_leave 1
bl_mode=$property
[ "$bl_mode" == "1" ] && error_and_leave 4
read_touch_property buildid || error_and_leave 1
str_cfg_id_new=${property#*-}
debug "firmware config ids: expected $str_cfg_id_latest, current $str_cfg_id_new"
notice "Touch firmware config id at boot time $str_cfg_id_boot"
notice "Touch firmware config id in the file $str_cfg_id_latest"
notice "Touch firmware config id currently programmed $str_cfg_id_new"
else
notice "Touch firmware is up to date"
fi
unset device_property hwrev_property
unset str_cfg_id_boot str_cfg_id_latest str_cfg_id_new
unset dec_cfg_id_boot dec_cfg_id_latest
unset hwrev_id product_id touch_product_id
unset touch_driver_link firmware_path touch_path
unset bl_mode dbg_on hw_mask firmware_file property
return 0