1#!/bin/bash
2# #########################################################
3# Script to run on witherspoon BMC to read/set vrm voltages
4
5
6# #########################################################
7function d2v() {
8    # usage:   d2v <decimal volts>
9
10    echo "$1" | awk '{print $1 * 256 + .5}' | cut -d '.' -f 1
11}
12
13
14# #########################################################
15function v2d() {
16    # usage:   v2d <hex val>
17
18    printf "	%0.3fV" "$(echo "$1" | awk '{print $1 / 256}')"
19}
20
21
22# #########################################################
23function i2d() {
24    # usage:  i2d <hex val> <current divisor>
25
26    # parse current mantisa and exponent
27    # format: SEEE ESMM MMMM MMMM
28    e=$(( $1/0x800 ))
29    esign=$(( e/0x10 ))
30    m=$(( $1 & 0x07FF ))
31    msign=$(( m/0x0400 ))
32
33    if [ $msign -eq 1 ]
34    then
35        # calc ones compliment
36        m=$(( (m^0x07FF)+1 ))
37        m=$(( -m ))
38    fi
39    if [ $esign -eq 1 ]
40    then
41        # calc ones compliment
42        e=$(( (e^0x1F)+1 ))
43        e=$(( -e ))
44    fi
45    printf "	%0.3fA\n" "$(echo $m $e "$2" | awk '{print ($1 * 2^$2)}')"
46}
47
48
49# #########################################################
50function rw_vc() {
51    # usage:   rw_vc <bus> <addr> <current divisor> <channel> <value>
52
53    # select channel
54    if [ "$4" != "x" ]
55    then
56        i2cset -y "$1" "$2" 0 "$4" b
57    fi
58
59    # write new voltage set point
60    if [ ! -e "$5" ]
61    then
62        i2cset -y "$1" "$2" 0x21 "$(d2v "$5")" w
63    fi
64
65    # print voltage set point
66    v2d "$(i2cget -y "$1" "$2" 0x21 w)"
67
68    # print voltage
69    v2d "$(i2cget -y "$1" "$2" 0x8B w)"
70
71    # print current
72    i2d "$(i2cget -y "$1" "$2" 0x8C w)" "$3"
73
74    # default back to channel 0
75    if [ "$4" != "x" ]
76    then
77        i2cset -y "$1" "$2" 0 0 b
78    fi
79}
80
81
82# #########################################################
83# Main
84
85if [ -e "$1" ]
86then
87    $0 vdda vcsa vdna vioa vddra vppa vddb vcsb vdnb viob vddrb vppb
88    exit
89fi
90
91if [ "$1" == "-h" ]
92then
93    echo "  Usage: vrm [<rail>=[value] [<rail>=[value]] ...]"
94    echo "    rail: vdda vcsa vdna vioa vddra vppa vddb vcsb vdnb viob vddrb vppb vdnd viod"
95    echo "    value: volts"
96    echo
97    echo "    e.g., vrm vioa=1.0 viob=1.0"
98    echo
99    exit
100fi
101
102echo "rail	set	read	current"
103echo "-------	------- ------- -------"
104for param in "${@:1}"
105do
106    rail=$(echo "$param" | cut -d'=' -f 1)
107    val=$(echo "${param}=" | cut -d'=' -f 2)
108    echo -n "$rail"
109    case "$rail" in
110        vdda)
111            rw_vc 4 0x70 2 0 "$val"
112            ;;
113        vddb)
114            rw_vc 5 0x70 2 0 "$val"
115            ;;
116        vcsa)
117            rw_vc 4 0x70 4 1 "$val"
118            ;;
119        vcsb)
120            rw_vc 5 0x70 4 1 "$val"
121            ;;
122        vdna)
123            rw_vc 4 0x71 2 0 "$val"
124            ;;
125        vdnb)
126            rw_vc 5 0x71 2 0 "$val"
127            ;;
128        vioa)
129            rw_vc 4 0x40 2 x "$val"
130            ;;
131        viob)
132            rw_vc 5 0x40 2 x "$val"
133            ;;
134        vddra)
135            rw_vc 4 0x71 2 1 "$val"
136            ;;
137        vddrb)
138            rw_vc 5 0x71 2 1 "$val"
139            ;;
140        vppa)
141            rw_vc 12 0x41 2 x "$val"
142            ;;
143        vppb)
144            rw_vc 13 0x41 2 x "$val"
145            ;;
146        vdnd)
147            rw_vc 2 0x70 2 0 "$val"
148            ;;
149        viod)
150            rw_vc 2 0x70 2 1 "$val"
151            ;;
152        *)
153            echo "	non-existant"
154    esac
155done
156