-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathbb-enable-spi-devicetree.sh
executable file
·158 lines (123 loc) · 4.79 KB
/
bb-enable-spi-devicetree.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/bin/sh
#
# This script modifies the flattened device-tree blob used by uboot on 3.8 and
# later kernels for BeagleBone (Black) to enable SPI1 and export the first
# chip-select line (cs0) as spidev device. The pinmux settings will also be
# set. After running this script, a reboot is required to load the modified
# device-tree.
#
# It should work on BeagleBone/Ubuntu, but might also work on other distros.
#
FDT_SPI_DEV="spi@481a0000"
UBOOTBASE="/boot"
FDTBASE="${UBOOTBASE}/dtbs/$(uname -r)"
FDT_SPI_PATH="/ocp/${FDT_SPI_DEV}"
REBOOT_REQUIRED=""
notif () {
echo "\033[1;34m${1}\033[0m${2}"
}
fail () {
echo "\033[1;31m${1}\033[0m${2}"
exit 0
}
checks () {
if ! [ $(id -u) = 0 ]; then
fail "you need to be root to run this (or use sudo)."
fi
has_fdttools=$(which fdtget 2>/dev/null)
if [ ! "${has_fdttools}" ]; then
fail "you need to install the device tree tools (apt-get install device-tree-compiler)."
fi
}
find_devicetree_file () {
EEPROM="/sys/bus/i2c/devices/1-0050/eeprom"
if [ ! -f "${EEPROM}" ]; then
EEPROM="/sys/bus/i2c/devices/0-0050/eeprom"
fi
if [ ! -f "${EEPROM}" ]; then
EEPROM="/sys/bus/i2c/devices/0-0050/at24-0/nvmem"
fi
if [ ! -f "${EEPROM}" ]; then
fail "i2c eeprom file not found in sysfs."
fi
board_type="$(hexdump -e '8/1 "%c"' "$EEPROM" -s 4 -n 8 2>&1)"
if [ -z ${board_type} ]; then
fail "failed to extract board type from eeprom."
fi
case $board_type in
"A335BONE") FDT="am335x-bone.dtb"; notif "detected BeagleBone";;
"A335BNLT") FDT="am335x-boneblack.dtb"; notif "detected BeagleBone Black";;
*) fail "failed to detect board type: unknown board \"$board_type\"";;
esac
if [ ! -f "${FDTBASE}/${FDT}" ]; then
fail "flattened device-tree file cannot be found at " "${FDTBASE}/${FDT}"
else
notif "found flattened device-tree at " "${FDTBASE}/${FDT}"
fi
}
enable_spi () {
SPISTATUS=$(fdtget "${FDTBASE}/${FDT}" "${FDT_SPI_PATH}" status 2>&1)
if [ "${SPISTATUS}" != "${SPISTATUS#*FDT_ERR_NOTFOUND}" ]; then
fail "path to spi device not found in flattened device-tree: " "${FDT_SPI_PATH}"
fi
if [ "${SPISTATUS}" = "okay" ]; then
notif "spi device at ${FDT_SPI_PATH} is already enabled, nothing to do."
else
fdtput -t s "${FDTBASE}/${FDT}" "${FDT_SPI_PATH}" "status" "okay" 2>&1
SPISTATUS=$(fdtget "${FDTBASE}/${FDT}" "${FDT_SPI_PATH}" status 2>&1)
if [ "${SPISTATUS}" != "okay" ]; then
fail "failed to enable spi device at ${FDT_SPI_PATH}. status is now: " ${SPISTATUS}
else
notif "successfully enabled " ${FDT_SPI_PATH}
REBOOT_REQUIRED="yes"
fi
fi
}
find_free_phandle () {
TREE="$1"
PHANDLE=
for i in $(seq 1 65535); do
p=$(printf "0x%x" $i)
has_phandle=$(grep "phandle = <$p>;" "${TREE}")
if [ -z "${has_phandle}" ]; then
echo "$p"
break
fi
done;
}
enable_spi_dev () {
SPIDEVSTATUS=$(fdtget "${FDTBASE}/${FDT}" "${FDT_SPI_PATH}/spidev@0" reg 2>&1)
if [ "${SPIDEVSTATUS}" = "${SPIDEVSTATUS#*FDT_ERR_NOTFOUND}" ]; then
notif "spidev at ${FDT_SPI_PATH}/spidev@0 already present, nothing to do."
else
FDTTEMP=$(mktemp -u)
DTSTEMP=$(mktemp -u)
DTSTEMP2=$(mktemp -u)
dtc -I dtb -O dts -o "${FDTTEMP}" "${FDTBASE}/${FDT}"
PHANDLE=$(find_free_phandle "${FDTTEMP}")
if [ -z "${PHANDLE}" ]; then
rm -f rm -f "${FDTTEMP}"
fail "failed to find a phandle for the pinmux settings."
fi
cat "${FDTTEMP}" | perl -ne "if (\$f>0 && /\};\$/) { print \"\n};\npinmux_spi1_pins \{\npinctrl-single,pins = <0x190 0x13 0x194 0x33 0x198 0x13 0x19c 0x13 0x164 0x12>;\nlinux,phandle = <${PHANDLE}>;\nphandle = <${PHANDLE}>;\n};\n\n\"; \$f=0; \$ff = 1;} else { print; } \$f=1 if (\$ff!=1 && /pinmux_userled_pins {/)" > "${DTSTEMP}"
cat "${DTSTEMP}" | perl -ne "if (\$f>0 && /\};\$/) { print \"\npinctrl-0 = <${PHANDLE}>;\nspidev: spidev\@0 \{\ncompatible = \\\"linux,spidev\\\";\nreg = <0>;\nspi-max-frequency = <24000000>;\n};\n};\n\n\"; \$f=0; \$ff=1;} else { print; } \$f=1 if (\$ff!=1 && /$(echo "${FDT_SPI_DEV}" | sed -nE "s/@/\\\@/p") {/)" > "${DTSTEMP2}"
dtc -I dts -O dtb -o "${FDTBASE}/${FDT}" ${DTSTEMP2}
#rm -f "${FDTTEMP}"
#rm -f "${DTSTEMP}"
#rm -f "${DTSTEMP2}"
SPIDEVSTATUS=$(fdtget "${FDTBASE}/${FDT}" "${FDT_SPI_PATH}/spidev@0" reg 2>&1)
if [ "0" = "${SPIDEVSTATUS}" ]; then
notif "successfully enabled " "${FDT_SPI_PATH}/spidev@0"
REBOOT_REQUIRED="yes"
else
fail "failed to enable " "${FDT_SPI_PATH}/spidev@0"
fi
fi
}
checks
find_devicetree_file
enable_spi
enable_spi_dev
if [ "yes" = "${REBOOT_REQUIRED}" ]; then
notif "please reboot."
fi