# Perform an i2c device configuration : instantiate / delete. # Input is of the form: # "echo [driver] > " # where operation = "new_device" or "delete_device" i2c_config() { local count=0 local MAX_BUS_RETRY=20 local MAX_I2C_OP_RETRY=10 i2c_bus_op=`echo "$@" | cut -d'>' -f 2` i2c_bus=$(dirname $i2c_bus_op) # check if bus exists while [[ "$count" -lt "$MAX_BUS_RETRY" ]]; do [[ -e $i2c_bus ]] && break || sleep .1 count=$((count+1)) done if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then echo "dell_i2c_utils : ERROR: $@ : i2c bus not created" return fi # perform the add/delete count=0 while [[ "$count" -lt "$MAX_I2C_OP_RETRY" ]]; do eval "$@" > /dev/null 2>&1 [[ $? == 0 ]] && break || sleep .2 count=$((count+1)) done if [[ "$count" -eq "$MAX_I2C_OP_RETRY" ]]; then echo "dell_i2c_utils : ERROR: $@ : i2c operation failed" return fi } # Check if a i2c bus exists. Poll for upto 2 seconds since mux creation may take time.. # Input: bus to check for existence i2c_poll_bus_exists() { local count=0 local MAX_BUS_RETRY=20 local i2c_bus i2c_bus=$1 # check if bus exists while [[ "$count" -lt "$MAX_BUS_RETRY" ]]; do [[ -e $i2c_bus ]] && break || sleep .1 count=$((count+1)) done if [[ "$count" -eq "$MAX_BUS_RETRY" ]]; then echo "dell_i2c_utils : ERROR: $@ : i2c bus not created" return 1 else return 0 fi } # Perform an i2c mux device create # Input is of the form: # i2c_mux_create mux_driver i2c_addr i2c_bus_num i2c_child_bus_num_start # where i2c_bus_num is the bus number in which the mux is to be created and # i2c_child_bus_num_start is the first of the 8 bus channels that this mux should create i2c_mux_create() { local MAX_MUX_CHANNEL_RETRY=3 local MAX_MUX_CHANNELS=8 local count=0 local i local mux_driver=$1 local i2c_addr=$2 local i2c_bus_num=$3 local i2c_child_bus_num_start=$4 # Construct the i2c bus, the first and last bus channels that will be created under the MUX i2c_bus=/sys/bus/i2c/devices/i2c-$i2c_bus_num i2c_mux_channel_first=$i2c_bus/i2c-$i2c_child_bus_num_start i2c_mux_channel_last=$i2c_bus/i2c-$(expr $i2c_child_bus_num_start + $MAX_MUX_CHANNELS - 1) if i2c_poll_bus_exists $i2c_bus; then while [[ "$count" -lt "$MAX_MUX_CHANNEL_RETRY" ]]; do eval "echo $mux_driver $i2c_addr > /sys/bus/i2c/devices/i2c-$i2c_bus_num/new_device" > /dev/null 2>&1 ret=$? # Give more time for the mux channels to get created based on retries i=0 while [[ "$i" -lt "$count" ]]; do sleep 1 i=$((i+1)) done # Check if the (first and last) mux channels got created if [[ $ret -eq "0" && -e $i2c_mux_channel_first && -e $i2c_mux_channel_last ]]; then break; else # If the channel did not get created, remove the mux, reset the mux tree and retry echo "dell_i2c_utils : ERROR: i2c mux channel not created for $mux_driver,$i2c_addr,$i2c_bus_num" i2c_mux_delete $i2c_addr $i2c_bus_num reset_muxes fi count=$((count+1)) done fi if [[ "$count" -eq "$MAX_MUX_CHANNEL_RETRY" ]]; then echo "dell_i2c_utils : ERROR: $1,$2 : i2c mux channel not created" return fi return } # Perform an i2c mux device delete # Input is of the form: # i2c_mux_delete i2c_addr i2c_bus_num i2c_mux_delete() { local i2c_addr local i2c_bus_num i2c_addr=$1 i2c_bus_num=$2 i2c_config "echo $i2c_addr > /sys/bus/i2c/devices/i2c-$i2c_bus_num/delete_device" }