1#!/bin/bash
2
3MODULE_PATH="/xyz/openbmc_project/inventory/system/board/Yosemite_4_Medusa_Board/MEDUSA_DELTA"
4
5dec_to_hex() {
6    local decimal=$1
7    local hex=""
8    local digits="0123456789ABCDEF"
9
10    while [ "$decimal" -gt 0 ]; do
11        remainder=$((decimal % 16))
12        hex="${digits:remainder:1}$hex"
13        decimal=$((decimal / 16))
14    done
15
16    # ensure the length of $hex >= 4
17    while [ ${#hex} -lt 4 ]; do
18        hex="0$hex"
19    done
20
21    echo "0x${hex:-0}"
22}
23
24read_mfr_id() {
25    local bus=$1
26    local addr=$2
27    local mfr_id
28    if mfr_id=$(i2ctransfer -f -y "$bus" w1@"$addr" 0x99 r5); then
29        local vendor="0x46 0x6c 0x65 0x78"
30        if [[ $mfr_id == *"$vendor"* ]]; then
31            echo "flex"
32        else
33            echo "delta"
34        fi
35        return 0
36    else
37        echo "i2ctransfer failed for MFR_ID" >&2
38        return 1 # return 1 on failure
39    fi
40}
41
42read_power_module() {
43    local bus=$1
44    local addr=$2
45    local pu_num=$3
46    local module_vendor
47
48    if ! module_vendor=$(read_mfr_id "$bus" "$addr"); then
49        log-create xyz.openbmc_project.State.Power.PowerRailFault --json \
50            "{\"POWER_RAIL\": \"${MODULE_PATH}${pu_num}_12V\", \"FAILURE_DATA\": \"Medusa Power Module ${pu_num} Fault\"}"
51        return # Return if read_mfr_id failed
52    fi
53
54    local failure_data="Medusa Power Module ${pu_num} Fault"
55    local power_rail="${MODULE_PATH}${pu_num}_12V"
56
57    # Read STATUS_BYTE (0x78) and STATUS_OTHER (0x7F) if flex type
58    if [ "$module_vendor" == "flex" ]; then
59        STATUS_BYTE=$(i2ctransfer -f -y "$bus" w1@"$addr" 0x78 r1)
60        local description="(0x78) STATUS_BYTE"
61        if [ -n "$failure_data" ]; then
62            failure_data="$failure_data, "
63        fi
64        failure_data+="$description: $STATUS_BYTE"
65
66        STATUS_OTHER=$(i2ctransfer -f -y "$bus" w1@"$addr" 0x7F r1)
67        local description="(0x7F) STATUS_OTHER"
68        if [ -n "$failure_data" ]; then
69            failure_data="$failure_data, "
70        fi
71        failure_data+="$description: $STATUS_OTHER"
72    fi
73
74    # Read STATUS_WORD (0x79)
75    read -r LOW_BYTE HIGH_BYTE <<< "$(i2ctransfer -f -y "$bus" w1@"$addr" 0x79 r2)"
76    STATUS_WORD=$((LOW_BYTE | (HIGH_BYTE << 8) ))
77    STATUS_WORD=$(dec_to_hex $STATUS_WORD)
78    local description="(0x79) STATUS_WORD"
79    if [ -n "$failure_data" ]; then
80        failure_data="$failure_data, "
81    fi
82    failure_data+="$description: $STATUS_WORD"
83
84    # Read other status registers (1 byte each)
85    for reg in 0x7A 0x7B 0x7C 0x7D 0x7E 0x80; do
86        STATUS=$(i2ctransfer -f -y "$bus" w1@"$addr" $reg r1)
87        case $reg in
88            0x7A) name="STATUS_VOUT";;
89            0x7B) name="STATUS_IOUT";;
90            0x7C) name="STATUS_INPUT";;
91            0x7D) name="STATUS_TEMPERATURE";;
92            0x7E) name="STATUS_CML";;
93            0x80) name="STATUS_MFR_SPECIFIC";;
94        esac
95        description="($reg) $name"
96        if [ -n "$failure_data" ]; then
97            failure_data="$failure_data, "
98        fi
99        failure_data+="$description: $STATUS"
100    done
101
102    # Send event
103    log-create xyz.openbmc_project.State.Power.PowerRailFault --json \
104        "{\"POWER_RAIL\": \"$power_rail\", \"FAILURE_DATA\": \"$failure_data\"}"
105}
106
107medusa_power_module_fault()
108{
109    if [ "$1" = "0" ]; then
110        read_power_module 11 0x62 "0"
111    elif [ "$1" = "1" ]; then
112        read_power_module 11 0x64 "1"
113    elif [ "$1" = "2" ]; then
114        read_power_module 11 0x65 "2"
115    elif [ "$1" = "3" ]; then
116        read_power_module 11 0x68 "3"
117    else
118        read_power_module 11 0x62 "0"
119        read_power_module 11 0x64 "1"
120        read_power_module 11 0x65 "2"
121        read_power_module 11 0x68 "3"
122    fi
123}
124
125medusa_power_module_fault "$1"
126