blob: 617eb32e792da9daa428a4df6f11957e8c6e3bf0 [file] [log] [blame]
#!/bin/sh
# Copyright 2017 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.
. /usr/share/misc/shflags
. /opt/google/touch/scripts/chromeos-touch-common.sh
DEFINE_boolean 'recovery' ${FLAGS_FALSE} "Recovery. Allows for rollback" 'r'
DEFINE_string 'device' '' "device name" 'd'
DEFINE_string 'device_path' '' "device path" 'p'
FW_LINK_NAME="wdt87xx.bin"
WDT_UTIL="/usr/sbin/wdt_util"
GET_ACTIVE_FW_VER="-v"
GET_ACTIVE_PARAM_VER="-c"
GET_ACTIVE_PROD_ID="-i"
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
update_firmware() {
local fw_path="$1"
local fw_param_ver="$2"
local ret
local cmd_log=""
for i in $(seq 3); do
cmd_log="$(
minijail0 -S /opt/google/touch/policies/wdt_util.update.policy \
"${WDT_UTIL}" -u "${fw_path}" -b -d "${FLAGS_device}"
)"
ret=$?
if [ ${ret} -eq 1 ]; then
return 0
fi
log_msg "FW update attempt #${i} failed: ${cmd_log}"
sleep 1
done
report_update_result "${FLAGS_device_path}" "${REPORT_RESULT_FAILURE}" \
"${fw_param_ver}"
die "Error updating touch firmware. ${ret}"
}
get_active_fw_param_ver() {
# Get the fw & param version of this device.
minijail0 -S /opt/google/touch/policies/wdt_util.query.policy \
"${WDT_UTIL}" "${GET_ACTIVE_FW_VER}" "${GET_ACTIVE_PARAM_VER}" -d \
"${FLAGS_device}"
}
get_active_product_id() {
# Get the product id of this device.
minijail0 -S /opt/google/touch/policies/wdt_util.query.policy \
"${WDT_UTIL}" "${GET_ACTIVE_PROD_ID}" -d "${FLAGS_device}"
}
compare_fw_versions() {
# Weida firmware versions are combined by two hexidecimal number. One is the
# FW version and the other one is the date code of parameters. To compare
# the active versions and the one we're considering, this function converts
# them to decimal first for the comparison, but displays them in their
# original hexidecimal form for clarity and simplicity in the logs.
local raw_active_fw_param_ver="$1"
local raw_active_fw_ver="${raw_active_fw_param_ver%_*}"
local raw_active_param_ver="${raw_active_fw_param_ver#"${raw_active_fw_ver}_"}"
local raw_fw_param_ver="$2"
local raw_fw_ver="${raw_fw_param_ver%_*}"
local raw_param_ver="${raw_fw_param_ver#"${raw_fw_ver}_"}"
local decimal_active_fw_ver="$(hex_to_decimal "$raw_active_fw_ver")"
local decimal_active_param_ver="$(hex_to_decimal "$raw_active_param_ver")"
local decimal_fw_ver="$(hex_to_decimal "$raw_fw_ver")"
local decimal_param_ver="$(hex_to_decimal "$raw_param_ver")"
compare_multipart_version "${decimal_active_fw_ver}" "${decimal_fw_ver}" \
"${decimal_active_param_ver}" "${decimal_param_ver}"
}
main() {
local device_name="${FLAGS_device}"
local active_product_id=""
local active_fw_param_ver=""
local fw_link_path=""
local fw_path=""
local fw_filename=""
local fw_name=""
local update_type=""
local update_needed=${FLAGS_FALSE}
local product_id=""
local fw_version=""
local product_fw=""
local fw_param_ver=""
# This script runs early at bootup, so if the touch driver is mistakenly
# included as a module (as opposed to being compiled directly in) the i2c
# device may not be present yet. Pause long enough for for people to notice
# and fix the kernel config.
check_i2c_chardev_driver
# Determine the product ID of the device we're considering updating
active_product_id="$(get_active_product_id)"
# Make sure there is a FW that looks like it's for the same product ID
fw_link_path="$(find_fw_link_path "${FW_LINK_NAME}" "${active_product_id}")"
log_msg "Attempting to load FW: '${fw_link_path}'"
fw_path="$(readlink "${fw_link_path}")"
if [ ! -e "${fw_link_path}" ] ||
[ ! -e "${fw_path}" ]; then
die "No valid firmware for weida-${active_product_id} found."
fi
# Parse out the version numbers for the new FW from it's filename
# The filename is as following format: product_fw_parameter.bin,
# like 01017401_2082_0133c65b.bin. 01017401 is the product id,
# 2082 is fw version and 0133c65b is the version of parameters.
fw_filename="${fw_path##*/}"
fw_name="${fw_filename%.bin}"
product_fw="${fw_name%_*}"
param_version="${fw_name#"${product_fw}_"}"
product_id="${product_fw%_*}"
fw_param_ver="${fw_name#"${product_id}_"}"
if [ -n "${active_product_id}" ] &&
[ "${product_id}" != "${active_product_id}" ]; then
log_msg "Current product id: ${active_product_id}"
log_msg "Updater product id: ${product_id}"
die "Touch firmware updater: Product ID mismatch!"
fi
# Get the current FW version that's loaded on the touch IC
active_fw_param_ver="$(get_active_fw_param_ver)"
log_msg "Product ID: ${product_id}"
log_msg "Current Firmware_parameters: ${active_fw_param_ver}"
log_msg "Updater Firmware_parameters: ${fw_param_ver}"
report_initial_version "${FLAGS_device_path}" "Weida HID" \
"${active_fw_param_ver}"
# Determine if an update is needed, and if we do, trigger it now
update_type="$(compare_fw_versions "${active_fw_param_ver}" \
"${fw_param_ver}")"
log_update_type "${update_type}"
update_needed="$(is_update_needed "${update_type}")"
if [ ${update_needed} -eq ${FLAGS_TRUE} ]; then
log_msg "Updating FW to ${fw_filename}..."
update_firmware "${fw_path}" "${fw_param_ver}"
active_fw_param_ver="$(get_active_fw_param_ver)"
log_msg "Current Firmware (after update attempt): ${active_fw_param_ver}"
update_type="$(compare_fw_versions "${active_fw_param_ver}" \
"${fw_param_ver}")"
if [ "${update_type}" -ne "${UPDATE_NOT_NEEDED_UP_TO_DATE}" ]; then
report_update_result "${FLAGS_device_path}" "${REPORT_RESULT_FAILURE}" \
"${fw_param_ver}"
die "Firmware update failed. Current Firmware: ${active_fw_param_ver}"
fi
log_msg "Update FW succeeded. Current Firmware: ${active_fw_param_ver}"
report_update_result "${FLAGS_device_path}" "${REPORT_RESULT_SUCCESS}" \
"${active_fw_param_ver}"
rebind_driver "${FLAGS_device_path}"
fi
exit 0
}
main "$@"