1#!/bin/bash 2# Copyright 2020 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16 17################################################################# 18# Prints CPLD version and save it in file /run/cpld0.version 19# 20# CPLD version format: Major.Minor.Point.Subpoint 21# 22# Major/Minor: base vendor image version, encoded in register 0x0 of the CPLD 23# I2C bus. 24# Major = higher 4 bits of register 0x00 25# Minor = lower 4 bits of register 0x00 26# Point/SubPoint: reserved as 0x0 for now 27# 28# e.g. reg[0] = 0x25 -> ver 2.5.0.0 29# 30################################################################# 31 32CPLD_I2C_BUS_NUM=13 33CPLD_I2C_BUS_ADDR='0x21' 34CPLD_I2C_BASEVER_REG='0x00' 35VER_ENV_FILE='/run/cpld0.version' 36 37################################################################# 38# Parse the byte value from i2cget and sanity checks the hex format 39# Arguments: 40# $1: i2c_bus_num 41# $2: i2c_bus_addr 42# $3: i2c_reg 43# Global: 44# 'byte_val' will be written with the numeric value from i2cget 45# Returns: 46# 0 if success, non-zero if failed to get the value or value is malformed 47################################################################# 48read_and_check_i2c_get() { 49 if ! (( $# == 3 )); then 50 echo "Usage: read_and_check_i2c_get i2c_bus_num i2c_bus_addr i2c_reg" 51 return 1 52 fi 53 54 local i2c_bus_num=$1 55 local i2c_bus_addr=$2 56 local i2c_reg=$3 57 58 local i2c_val_raw 59 i2c_val_raw=$(i2cget -y "${i2c_bus_num}" "${i2c_bus_addr}" "${i2c_reg}") || return 60 61 # Verify that it is of format 0x[hex][hex]. 62 local HEXBYTE_RE='^0x[0-9A-Fa-f]{2}$' 63 if ! [[ ${i2c_val_raw} =~ ${HEXBYTE_RE} ]]; then 64 echo "i2cget $* outputs invalid value: ${i2c_val_raw}" 65 return 1 66 fi 67 68 ((byte_val = i2c_val_raw)) 69 return 0 70} 71 72################################################################# 73# Prints CPLD version in Major.Minor.Point.Subpoint format. 74# Each dot separated field is decimal number with no leading zeros. 75# Arguments: 76# None 77# Globals: 78# Write parsed version into the following global variables: 79# cpld_ver_major 80# cpld_ver_minor 81# cpld_point 82# cpld_subpoint 83# Returns: 84# 0 if success, non-zero otherwise 85################################################################# 86parse_cpld_ver() { 87 # Stores the output of read_and_check_i2c_get 88 local byte_val 89 90 # Read a byte, assign higher 4 bits to cpld_ver_major and lower 4 bits to 91 # cpld_ver_minor. 92 # e.g. cpld_ver_raw = 0x09 => major_hex = 0, minor_hex = 9 93 read_and_check_i2c_get ${CPLD_I2C_BUS_NUM} ${CPLD_I2C_BUS_ADDR} ${CPLD_I2C_BASEVER_REG} || 94 return 95 local cpld_ver 96 ((cpld_ver = byte_val)) 97 ((cpld_ver_major = cpld_ver >> 4)) 98 ((cpld_ver_minor = cpld_ver & 0xf)) 99 ((cpld_point = 0)) 100 ((cpld_subpoint = 0)) 101 102 return 0 103} 104 105main() { 106 local cpld_ver_major 107 local cpld_ver_minor 108 local cpld_point 109 local cpld_subpoint 110 111 parse_cpld_ver || return 112 113 # Write CPLD version to file. 114 cpld_ver="${cpld_ver_major}.${cpld_ver_minor}.${cpld_point}.${cpld_subpoint}" 115 echo "CPLD version ${cpld_ver}" 116 echo "${cpld_ver}" > "${VER_ENV_FILE}" 117 118 return 0 119} 120 121# Exit without running main() if sourced 122if ! (return 0 2>/dev/null); then 123 main "$@" 124fi 125