| #!/bin/sh |
| # Copyright 2021 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="himax_i2chid.bin" |
| HX_UTIL="/usr/sbin/hx_util" |
| GET_ACTIVE_FW_VER="-v" |
| GET_ACTIVE_PROD_ID="-p" |
| |
| # Parse command line |
| FLAGS "$@" || exit 1 |
| eval set -- "${FLAGS_ARGV}" |
| |
| update_firmware() { |
| local fw_path="$1" |
| local fw_param_ver="$2" |
| local i |
| local ret |
| local cmd_log="" |
| |
| for i in $(seq 3); do |
| cmd_log="$( |
| minijail0 -u fwupdate-i2c -g fwupdate-i2c \ |
| -G -I -N -n -p -v --uts -e \ |
| -S /opt/google/touch/policies/hx_util.update.policy \ |
| "${HX_UTIL}" -u "${fw_path}" -d "${FLAGS_device}" |
| )" |
| |
| ret=$? |
| if [ ${ret} -eq 0 ]; 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 -u fwupdate-i2c -g fwupdate-i2c \ |
| -G -I -N -n -p -v --uts -e \ |
| -S /opt/google/touch/policies/hx_util.query.policy \ |
| "${HX_UTIL}" "${GET_ACTIVE_FW_VER}" -d "${FLAGS_device}" |
| } |
| |
| get_active_product_id() { |
| # Get the product id of this device. |
| minijail0 -u fwupdate-i2c -g fwupdate-i2c \ |
| -G -I -N -n -p -v --uts -e \ |
| -S /opt/google/touch/policies/hx_util.query.policy \ |
| "${HX_UTIL}" "${GET_ACTIVE_PROD_ID}" -d "${FLAGS_device}" |
| } |
| |
| main() { |
| 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 product_fw="" |
| local fw_param_ver="" |
| |
| # 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 himax i2chid ${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%_*}" |
| 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}" "Himax HID" \ |
| "${active_fw_param_ver}" |
| |
| # Determine if an update is needed, and if we do, trigger it now |
| update_type="$(compare_multipart_version "$((0x${active_fw_param_ver}))" \ |
| "$((0x${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_multipart_version "$((0x${active_fw_param_ver}))" \ |
| "$((0x${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 "$@" |