1#!/system/bin/sh
2
3PATH=/sbin:/system/sbin:/system/bin:/system/xbin
4export PATH
5
6while getopts d op;
7do
8	case $op in
9		d)  dbg_on=1;;
10	esac
11done
12shift $(($OPTIND-1))
13
14scriptname=${0##*/}
15
16uppers=ABCDEFP1234567890
17lowers=abcdefp1234567p9
18
19convert_to_pnotation()
20{
21	result=""
22	let i=0
23	while ([ $i -lt ${#1} ]) do
24		sym=${1:$i:1}
25		case $uppers in
26			*$sym*) sym=${uppers%$sym*}; result="${result}${lowers:${#sym}:1}";;
27			*) result="${result}$sym";;
28		esac
29		i=$((i + 1))
30	done
31	echo "$result"
32	unset i result
33}
34
35debug()
36{
37	[ $dbg_on ] && echo "Debug: $*"
38}
39
40notice()
41{
42	echo "$*"
43	echo "$scriptname: $*" > /dev/kmsg
44}
45
46error_and_leave()
47{
48	local err_msg
49	local err_code=$1
50	case $err_code in
51		1)  err_msg="Error: No response from touch IC";;
52		2)  err_msg="Error: Cannot read property $1";;
53		3)  err_msg="Error: No matching firmware file found";;
54		4)  err_msg="Error: Touch IC is in bootloader mode";;
55		5)  err_msg="Error: Touch provides no reflash interface";;
56		6)  err_msg="Error: Touch driver is not running";;
57	esac
58	notice "$err_msg"
59	exit $err_code
60}
61
62for touch_vendor in $*; do
63	debug "searching driver for vendor [$touch_vendor]"
64	touch_driver_link=$(ls -l /sys/bus/i2c/drivers/$touch_vendor*/*-*)
65	if [ -z "$touch_driver_link" ]; then
66		debug "no driver for vendor [$touch_vendor] is running"
67		shift 1
68	else
69		debug "driver for vendor [$touch_vendor] found!!!"
70		break
71	fi
72done
73
74[ -z "$touch_driver_link" ] && error_and_leave 6
75
76touch_path=/sys/devices/${touch_driver_link#*devices/}
77debug "sysfs touch path: $touch_path"
78
79[ -f $touch_path/doreflash ] || error_and_leave 5
80[ -f $touch_path/poweron ] || error_and_leave 5
81
82debug "wait until driver reports <ready to flash>..."
83while true; do
84	readiness=$(cat $touch_path/poweron)
85	if [ "$readiness" == "1" ]; then
86		debug "ready to flash!!!"
87		break;
88	fi
89	sleep 1
90	debug "not ready; keep waiting..."
91done
92unset readiness
93
94device_property=ro.boot.device
95hwrev_property=ro.boot.hwrev
96firmware_path=/system/vendor/firmware
97
98let dec_cfg_id_boot=0; dec_cfg_id_latest=0;
99
100read_touch_property()
101{
102	property=""
103	debug "retrieving property: [$touch_path/$1]"
104	property=$(cat $touch_path/$1 2> /dev/null)
105	debug "touch property [$1] is: [$property]"
106	[ -z "$property" ] && return 1
107	return 0
108}
109
110find_latest_config_id()
111{
112	debug "scanning dir for files matching [$1]"
113	str_cfg_id_latest=""
114	let dec=0; max=0;
115	for file in $(ls $1 2>/dev/null);
116	do
117		x=${file#*-}; z=${x#*-}; str_hex=${z%%-*};
118		let dec=0x$str_hex
119		if [ $dec -gt $max ];
120		then
121			let max=$dec; dec_cfg_id_latest=$dec;
122			str_cfg_id_latest=$str_hex
123		fi
124	done
125	unset dec max x z str_hex
126	[ -z "$str_cfg_id_latest" ] && return 1
127	return 0
128}
129
130read_touch_property flashprog || error_and_leave 1
131bl_mode=$property
132debug "bl mode: $bl_mode"
133
134read_touch_property productinfo || error_and_leave 1
135touch_product_id=$property
136if [ -z "$touch_product_id" ] || [ "$touch_product_id" == "0" ];
137then
138	debug "touch ic reports invalid product id"
139	error_and_leave 3
140fi
141debug "touch product id: $touch_product_id"
142
143read_touch_property buildid || error_and_leave 1
144str_cfg_id_boot=${property#*-}
145let dec_cfg_id_boot=0x$str_cfg_id_boot
146debug "touch config id: $str_cfg_id_boot"
147
148product_id=$(getprop $device_property 2> /dev/null)
149[ -z "$product_id" ] && error_and_leave 2 $device_property
150product_id=${product_id%-*}
151debug "product id: $product_id"
152
153hwrev_id=$(getprop $hwrev_property 2> /dev/null)
154[ -z "$hwrev_id" ] && error_and_leave 2 $hwrev_property
155hwrev_id=${hwrev_id#*x}
156hwrev_id=$(convert_to_pnotation $hwrev_id)
157debug "hw revision: $hwrev_id"
158
159cd $firmware_path
160
161debug "search for best hw revision match"
162hw_mask="-$hwrev_id"
163while [ ! -z "$hw_mask" ]; do
164	if [ "$hw_mask" == "-" ]; then
165		hw_mask=""
166	fi
167	find_latest_config_id "$touch_vendor-$touch_product_id-*-$product_id$hw_mask.*"
168	if [ $? -eq 0 ]; then
169		break;
170	fi
171        hw_mask=${hw_mask%?}
172done
173
174[ -z "$str_cfg_id_latest" ] && error_and_leave 3
175
176firmware_file=$(ls $touch_vendor-$touch_product_id-$str_cfg_id_latest-*-$product_id$hw_mask.*)
177debug "firmware file for upgrade $firmware_file"
178
179if [ $dec_cfg_id_boot -ne $dec_cfg_id_latest ] || [ "$bl_mode" == "1" ];
180then
181	debug "forcing firmware upgrade"
182	echo 1 > $touch_path/forcereflash
183	debug "sending reflash command"
184	echo $firmware_file > $touch_path/doreflash
185	read_touch_property flashprog || error_and_leave 1
186	bl_mode=$property
187
188	[ "$bl_mode" == "1" ] && error_and_leave 4
189
190	read_touch_property buildid || error_and_leave 1
191	str_cfg_id_new=${property#*-}
192	debug "firmware config ids: expected $str_cfg_id_latest, current $str_cfg_id_new"
193
194	notice "Touch firmware config id at boot time $str_cfg_id_boot"
195	notice "Touch firmware config id in the file $str_cfg_id_latest"
196	notice "Touch firmware config id currently programmed $str_cfg_id_new"
197else
198	notice "Touch firmware is up to date"
199fi
200
201unset device_property hwrev_property
202unset str_cfg_id_boot str_cfg_id_latest str_cfg_id_new
203unset dec_cfg_id_boot dec_cfg_id_latest
204unset hwrev_id product_id touch_product_id
205unset touch_driver_link firmware_path touch_path
206unset bl_mode dbg_on hw_mask firmware_file property
207
208return 0
209