summaryrefslogtreecommitdiff
path: root/util/flash_fp_mcu_common.sh
blob: ef70bc61e10d1bc530de04864992504da31d2768 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/bin/bash
# Copyright 2019 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

DEFINE_boolean 'read' "${FLAGS_FALSE}" 'Read instead of write' 'r'
FLAGS_HELP="Usage: ${0} [flags] ec.bin"

# Process commandline flags
FLAGS "${@}" || exit 1
eval set -- "${FLAGS_ARGV}"

if [[ "$#" -eq 0 ]]; then
  echo "Missing filename"
  flags_help
  exit 1
fi

# print out canonical path to differentiate between /usr/local/bin and
# /usr/bin installs
echo "$(readlink -f "$0")"

readonly CROS_EC_SPI_MODALIAS_STR="of:NcrfpTCgoogle,cros-ec-spi"

check_hardware_write_protect_disabled() {
  local hardware_write_protect_state="$(crossystem wpsw_cur)"
  if [[ "${hardware_write_protect_state}" != "0" ]]; then
    echo "Please make sure hardware write protect is disabled."
    echo "See https://www.chromium.org/chromium-os/firmware-porting-guide/firmware-ec-write-protection"
    exit 1
  fi
}

# Get the spiid for the fingerprint sensor based on the modalias
# string: https://crbug.com/955117
get_spiid() {
  for dev in /sys/bus/spi/devices/*; do
    if [[ "$(cat "${dev}/modalias")" == "${CROS_EC_SPI_MODALIAS_STR}" ]]; then
      echo "$(basename "${dev}")"
      exit 0
    fi
  done

  exit 1
}

flash_fp_mcu_stm32() {
  local spidev="${1}"
  local gpio_nrst="${2}"
  local gpio_boot0="${3}"
  local gpio_pwren="${4}"
  local file="${5}"
  local spiid

  local STM32MON_READ_FLAGS=" -U -u -p -s ${spidev} -r"
  local STM32MON_WRITE_FLAGS="-U -u -p -s ${spidev} -e -w"
  local stm32mon_flags=""

  if [[ "${FLAGS_read}" -eq "${FLAGS_TRUE}" ]]; then
    if [[ -e "${file}" ]]; then
      echo "Output file already exists: ${file}"
      exit 1
    fi
    stm32mon_flags="${STM32MON_READ_FLAGS}"
  else
    if [[ ! -f "${file}" ]]; then
      echo "Invalid image file: ${file}"
      exit 1
    fi
    stm32mon_flags="${STM32MON_WRITE_FLAGS}"
  fi

  check_hardware_write_protect_disabled

  spiid="$(get_spiid)"
  if [[ $? -ne 0 ]]; then
    echo "Unable to find FP sensor SPI device: ${CROS_EC_SPI_MODALIAS_STR}"
    exit 1
  fi

  echo "Flashing SPI device ID: ${spiid}"

  # Ensure the ACPI is not cutting power when unloading cros-ec-spi
  if [[ -n "${gpio_pwren}" ]]; then
    echo "${gpio_pwren}" > /sys/class/gpio/export
    echo "out" > "/sys/class/gpio/gpio${gpio_pwren}/direction"
    echo 1 > "/sys/class/gpio/gpio${gpio_pwren}/value"
  fi

  # Remove cros_fp if present
  echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/unbind

  # Configure the MCU Boot0 and NRST GPIOs
  echo "${gpio_boot0}" > /sys/class/gpio/export
  echo "out" > "/sys/class/gpio/gpio${gpio_boot0}/direction"
  echo "${gpio_nrst}" > /sys/class/gpio/export
  echo "out" > "/sys/class/gpio/gpio${gpio_nrst}/direction"

  # Reset sequence to enter bootloader mode
  echo 1 > "/sys/class/gpio/gpio${gpio_boot0}/value"
  echo 0 > "/sys/class/gpio/gpio${gpio_nrst}/value"
  sleep 0.001

  # load spidev (fail on cros-ec-spi first to change modalias)
  echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/bind 2>/dev/null
  echo "${spiid}" > /sys/bus/spi/drivers/spidev/bind

  # Release reset as the SPI bus is now ready
  echo 1 > "/sys/class/gpio/gpio${gpio_nrst}/value"
  echo "in" > "/sys/class/gpio/gpio${gpio_nrst}/direction"

  stm32mon ${stm32mon_flags} "${file}"

  # unload spidev
  echo "${spiid}" > /sys/bus/spi/drivers/spidev/unbind

  # Go back to normal mode
  echo "out" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
  echo 0 > "/sys/class/gpio/gpio${gpio_boot0}/value"
  echo 0 > "/sys/class/gpio/gpio${gpio_nrst}/value"
  echo 1 > "/sys/class/gpio/gpio${gpio_nrst}/value"

  # Give up GPIO control
  echo "in" > "/sys/class/gpio/gpio${gpio_boot0}/direction"
  echo "in" > "/sys/class/gpio/gpio${gpio_nrst}/direction"
  echo "${gpio_boot0}" > /sys/class/gpio/unexport
  echo "${gpio_nrst}" > /sys/class/gpio/unexport

  # wait for FP MCU to come back up (including RWSIG delay)
  sleep 2
  # Put back cros_fp driver
  echo "${spiid}" > /sys/bus/spi/drivers/cros-ec-spi/bind
  # Kernel driver is back, we are no longer controlling power
  if [[ -n "${gpio_pwren}" ]]; then
    echo "${gpio_pwren}" > /sys/class/gpio/unexport
  fi
  # Test it
  ectool --name=cros_fp version
}