1#!/bin/bash
2# Copyright 2020 Google LLC
3# Copyright 2020 Quanta Computer Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17#
18# Common GPIO functions.
19
20# Map names of GPIOs to GPIO number
21declare -A GPIO_NAMES_TO_NUMBER=(
22  ['RST_BMC_PHY_N']=15
23  ['BMC_BRD_REV_ID6']=37
24  ['BMC_BRD_REV_ID5']=38
25  ['BMC_BRD_SKU_ID3']=39
26  ['BMC_BRD_SKU_ID2']=40
27  ['FM_BMC_CPU_UART_EN']=76
28  ['RST_BMC_RSMRST_N']=87
29  ['RST_KBRST_BMC_CPLD_N']=94
30  ['FAN_BRD_REV_ID0']=122
31  ['FAN_BRD_REV_ID1']=123
32  ['HSBP_BRD_REV_ID3']=124
33  ['HSBP_BRD_REV_ID2']=125
34  ['HSBP_BRD_REV_ID1']=126
35  ['BMC_BRD_REV_ID0']=136
36  ['BMC_BRD_REV_ID1']=137
37  ['BMC_BRD_REV_ID2']=138
38  ['BMC_BRD_REV_ID3']=139
39  ['BMC_BRD_REV_ID4']=140
40  ['BMC_BRD_SKU_ID0']=141
41  ['BMC_BRD_SKU_ID1']=142
42  ['HDD_PRSNT_N']=160
43  ['SPI_SW_SELECT']=169
44  ['BMC_BRD_REV_ID7']=194
45  ['HSBP_BRD_REV_ID0']=196
46)
47
48# 1 is active_low 0 is active_high
49declare -A GPIO_NAMES_TO_ACTIVE_LOW=(
50  ['RST_BMC_PHY_N']=1
51  ['BMC_BRD_REV_ID6']=0
52  ['BMC_BRD_REV_ID5']=0
53  ['BMC_BRD_SKU_ID3']=0
54  ['BMC_BRD_SKU_ID2']=0
55  ['FM_BMC_CPU_UART_EN']=0
56  ['RST_BMC_RSMRST_N']=1
57  ['RST_KBRST_BMC_CPLD_N']=1
58  ['FAN_BRD_REV_ID0']=0
59  ['FAN_BRD_REV_ID1']=0
60  ['HSBP_BRD_REV_ID3']=0
61  ['HSBP_BRD_REV_ID2']=0
62  ['HSBP_BRD_REV_ID1']=0
63  ['BMC_BRD_REV_ID0']=0
64  ['BMC_BRD_REV_ID1']=0
65  ['BMC_BRD_REV_ID2']=0
66  ['BMC_BRD_REV_ID3']=0
67  ['BMC_BRD_REV_ID4']=0
68  ['BMC_BRD_SKU_ID0']=0
69  ['BMC_BRD_SKU_ID1']=0
70  ['HDD_PRSNT_N']=1
71  ['SPI_SW_SELECT']=0
72  ['BMC_BRD_REV_ID7']=0
73  ['HSBP_BRD_REV_ID0']=0
74)
75
76##################################################
77# Initializes the gpio state
78# This operation is idempotent and can be applied
79# repeatedly to the same gpio. It will make sure the
80# gpio ends up in the initialized state even if it
81# was.
82# Arguments:
83#   $1: GPIO name
84# Return:
85#   0 if success, non-zero if error
86##################################################
87init_gpio() {
88  if (( $# != 1 )); then
89    echo "Usage: init_gpio name" >&2
90    return 1
91  fi
92
93  local name=$1
94
95  local number=${GPIO_NAMES_TO_NUMBER["${name}"]}
96  if [[ -z ${number} ]]; then
97    echo "Missing number info for: ${name}" >&2
98    return 2
99  fi
100
101  local active_low=${GPIO_NAMES_TO_ACTIVE_LOW["${name}"]}
102  if [[ -z ${active_low} ]]; then
103    echo "Missing active_low info for: ${name}" >&2
104    return 2
105  fi
106
107  if [[ ! -e "/sys/class/gpio/gpio${number}" ]]; then
108    echo "${number}" >'/sys/class/gpio/export'
109  fi
110  echo "${active_low}" >"/sys/class/gpio/gpio${number}/active_low"
111}
112
113##################################################
114# Set output GPIO direction.
115# Arguments:
116#   $1: GPIO name
117#   $2: GPIO direction, "high" or "low"
118# Return:
119#   0 if success, non-zero if error
120##################################################
121set_gpio_direction() {
122  if (( $# != 2 )); then
123    echo 'Usage: set_gpio_direction name direction' >&2
124    return 1
125  fi
126
127  local name=$1
128  local direction=$2
129
130  local number=${GPIO_NAMES_TO_NUMBER["${name}"]}
131  if [[ -z ${number} ]]; then
132    echo "Missing number info for: ${name}" >&2
133    return 2
134  fi
135
136  init_gpio "${name}" || return
137  echo "${direction}" >"/sys/class/gpio/gpio${number}/direction"
138  echo "Set gpio ${name} #${number} to direction ${direction}" >&2
139}
140
141##################################################
142# Get GPIO value
143# Arguments:
144#   $1: GPIO name
145# Return:
146#   0 if success, non-zero if error
147#   stdout: The value of the gpio
148##################################################
149get_gpio_value() {
150  if (( $# != 1 )); then
151    echo 'Usage: get_gpio_value name' >&2
152    return 1
153  fi
154
155  local name=$1
156
157  local number=${GPIO_NAMES_TO_NUMBER["${name}"]}
158  if [[ -z ${number} ]]; then
159    echo "Missing number info for: ${name}" >&2
160    return 2
161  fi
162
163  init_gpio "${name}" || return
164  cat "/sys/class/gpio/gpio${number}/value"
165}
166