#!/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