blob: bd7b9bd47a7ed516980e2eae0c2b8c59e1079fe3 [file] [log] [blame] [edit]
#!/bin/sh
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Chrome OS Touch Config Update Script
# This script checks whether a payload config in rootfs should be applied
# to the touch device. If so, this will trigger the update_config mechanism in
# the kernel driver. The config update mechanism is a unique feature of
# Atmel mXT touchscreen and touchpad devices.
#
. /usr/share/misc/shflags
. /opt/google/touch/scripts/chromeos-touch-common.sh
DEFINE_boolean 'force' ${FLAGS_FALSE} "Force update" 'f'
DEFINE_string 'device' 'atmel_mxt_ts' "device name" 'd'
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
get_device_config_csum() {
# Convert to lowercase.
echo "$(cat "$1/config_csum")" | tr [:upper:] [:lower:]
}
get_file_config_csum() {
# Config checksum is at line 4 of the raw config file.
# Get rid of the Windows newline character and convert to lowercase.
sed -n 4p "$1" | tr -cd "[:print:]" | tr [:upper:] [:lower:]
}
get_config_file_name() {
local config_file_mapping="$1"
local touch_device_path="$2"
local board=`grep CHROMEOS_RELEASE_BOARD= /etc/lsb-release | awk -F = '{print $2}'`
if [ ! -e "${touch_device_path}/T19_status" ]; then
die "No T19_Status for ${touch_device_path}"
return
fi
# Only support 2 different configs for now.
read T19_status1 config1 T19_status2 config2 < "${config_file_mapping}"
# T19 status report is async, so lets try a few times.
printf "1" > "${touch_device_path}/T19_status"
for i in $(seq 5); do
local T19="$(cat "${touch_device_path}/T19_status")"
local T19_decimal=""
local mask="$((0xff))"
local sensor_identifier=""
local status1_sensor=""
local status2_sensor=""
case "${board}" in clapper|clapper-*)
mask="$((0x03))"
;;
esac
T19_decimal="$((0x${T19}))"
sensor_identifier="$(($T19_decimal & $mask))"
status1_sensor="$(($((0x$T19_status1)) & $mask))"
status2_sensor="$(($((0x$T19_status2)) & $mask))"
if [ "${sensor_identifier}" = "${status1_sensor}" ]; then
echo "${config1}"
return
elif [ "${sensor_identifier}" = "${status2_sensor}" ]; then
echo "${config2}"
return
fi
sleep 1
done
die "No matching config found"
}
update_config() {
local touch_device_path="$1"
local config_file_path="$2"
local device_config_csum="$(get_device_config_csum "${touch_device_path}")"
local file_config_csum="$(get_file_config_csum "${config_file_path}")"
local i
log_msg "Device config checksum : ${device_config_csum}"
log_msg "New config checksum : ${file_config_csum}"
report_initial_config "${touch_device_path}" "${device_config_csum}"
if [ "${device_config_csum}" != "${file_config_csum}" ] ||
[ ${FLAGS_force} -eq ${FLAGS_TRUE} ]; then
printf 1 > "${touch_device_path}/update_config"
local ret=$?
if [ ${ret} -ne 0 ]; then
report_config_result "${touch_device_path}" "${REPORT_RESULT_FAILURE}" \
"${file_config_csum}"
die "Config update failed. ret=${ret}"
fi
# Sleep for a while to allow the device config checksum gets updated.
# No latency concern here since config update happens rarely -- not
# every boot but only when new set of config data is needed.
for i in $(seq 5); do
sleep 1
device_config_csum="$(get_device_config_csum "${touch_device_path}")"
log_msg "Try #${i}: Checking new device csum ${device_config_csum}"
if [ "${device_config_csum}" = "${file_config_csum}" ]; then
log_msg "Config update succeeded"
report_config_result "${touch_device_path}" "${REPORT_RESULT_SUCCESS}" \
"${device_config_csum}"
exit 0
fi
done
report_config_result "${touch_device_path}" "${REPORT_RESULT_FAILURE}" \
"${file_config_csum}"
die "Config update failed. config_sum mismatched after update."
else
log_msg "Config is up-to-date, no need to update"
fi
}
main() {
local touch_device_name="${FLAGS_device}"
local touch_device_path=""
local config_file_name=""
local ts_config_mapping="/opt/google/touch/config/ts_config_mapping"
local tp_config_file_name="maxtouch-tp.cfg"
local ts_config_file_name="maxtouch-ts.cfg"
local config_link_path=""
local config_file_path=""
touch_device_path="$(find_i2c_device_by_name "${touch_device_name}" \
"update_config config_csum")"
if [ -z "${touch_device_path}" ]; then
die "${touch_device_name} not found on system."
fi
case "${touch_device_name}" in
*ts*|ATML0001*)
if [ -e "${ts_config_mapping}" ]; then
config_file_name="$(get_config_file_name "${ts_config_mapping}" \
"${touch_device_path}")"
log_msg "Using ts_config_mapping to find config '${config_file_name}'"
else
config_file_name="${ts_config_file_name}"
fi
;;
*tp*|ATML0000*)
config_file_name="${tp_config_file_name}"
;;
*)
die "No valid touch device name ${touch_device_name}."
;;
esac
config_link_path="/lib/firmware/${config_file_name}"
config_file_path="$(readlink -f "${config_link_path}")"
if [ ! -e "${config_link_path}" ] ||
[ ! -e "${config_file_path}" ]; then
die "No valid config file with name ${config_file_name} found."
fi
if [ ! -e "${touch_device_path}/config_file" ] ||
[ ! -e "${touch_device_path}/update_config" ]; then
die "Sysfs entry for config update not found."
fi
printf "${config_file_name}" > "${touch_device_path}/config_file"
if [ "$(cat "${touch_device_path}/config_file")" != "${config_file_name}" ]
then
die "Can't set config file name to ${config_file_name}"
fi
update_config "${touch_device_path}" "${config_file_path}"
exit 0
}
main "$@"