-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdtslots.go
237 lines (216 loc) · 6.17 KB
/
dtslots.go
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/// Author: Bernhard Tittelbach, btittelbach@github (c) 2015
package bbhw
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"strconv"
)
var foundit_error_ error
var ERROR_DTO_ALREADY_LOADED error
var dtsslot_slots_file_ string
var dtsslot_ocp_dir_ string = ""
var dtsslot_path_ocp_regex_ *regexp.Regexp = regexp.MustCompile("^/sys/devices(?:/platform)?/ocp" + `(?:\.\d+)?`)
var dtsslot_path_base_ string = "/sys/devices"
func init() {
foundit_error_ = fmt.Errorf("Success")
ERROR_DTO_ALREADY_LOADED = fmt.Errorf("DeviceTreeOverlay is already loaded")
}
func doesPathExist(name string) bool {
_, err := os.Stat(name)
return err == nil || !os.IsNotExist(err)
}
func findFile(basedir, searchdirregex, searchfilename string, maxdepth int) (sfile string, err error) {
var dir_regex *regexp.Regexp
if dir_regex, err = regexp.Compile(filepath.Join(basedir, searchdirregex)); err != nil {
return "", err
}
err = filepath.Walk(basedir, makeFindDirHelperFunc(&sfile, dir_regex, maxdepth))
if err == foundit_error_ {
err = nil
} else if err == nil {
err = fmt.Errorf("Directory Not Found: %s/%s", basedir, searchdirregex)
return
}
sfile = filepath.Join(sfile, searchfilename)
if !doesPathExist(sfile) {
return "", err
}
return
}
func findFileInSubDirectory(basedir, dirglobexpr string, searchfilename string) (sfile string, err error) {
var slist []string
slist, err = filepath.Glob(filepath.Join(basedir, dirglobexpr))
if err != nil {
return
}
for _, path := range slist {
sfile = filepath.Join(path, searchfilename)
if doesPathExist(sfile) {
return
}
}
sfile = ""
err = fmt.Errorf("findFileInSubDirectory(%s,%s,%s) could not be found", basedir, dirglobexpr, searchfilename)
return
}
func makeFindDirHelperFunc(returnvalue *string, target_re *regexp.Regexp, maxdepth int) func(string, os.FileInfo, error) error {
return func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
return nil
}
if len(filepath.SplitList(path)) > maxdepth {
return filepath.SkipDir
}
if target_re.MatchString(path) {
*returnvalue = path
return foundit_error_ //foundit
}
return nil //continue walking
}
}
// Singelton Function .. unlikely that slot file moves between reboots
func findSlotsFile() (sfile string, err error) {
if len(dtsslot_slots_file_) > 0 {
return dtsslot_slots_file_, nil
}
sfile, err = findFile(dtsslot_path_base_, "(?:platform)?/bone_capemgr"+`(?:\.\d+)?`+"$", "slots", 5)
if err != nil {
err = fmt.Errorf("OverlaySlotsFile Not Found")
sfile = ""
return
}
dtsslot_slots_file_ = sfile
return
}
func findOCPDir() (path string, err error) {
if len(dtsslot_ocp_dir_) > 0 {
return dtsslot_ocp_dir_, nil
} else {
err = filepath.Walk(dtsslot_path_base_, makeFindDirHelperFunc(&path, dtsslot_path_ocp_regex_, 6))
if err == foundit_error_ && len(path) > 0 {
dtsslot_ocp_dir_ = path
err = nil
return
} else if err == nil {
err = fmt.Errorf("OCP directory not found")
}
}
return
}
func findOverlayStateFile(dtb_name string) (sfile string, err error) {
var ocp_dir string
if ocp_dir, err = findOCPDir(); err != nil {
return
}
// sfile, err = findFile(ocp_dir, "(?:ocp:)?"+dtb_name+"(?:_pinmux)?", "state", 7)
sfile, err = findFileInSubDirectory(ocp_dir, "*"+dtb_name+"*", "state")
if err != nil {
err = fmt.Errorf("Overlay state file not found")
sfile = ""
return
}
return
}
func AddDeviceTreeOverlay(dtb_name string) (err error) {
var slotsfilename string
var slotsfh *os.File
slotsfilename, err = findSlotsFile()
if err != nil {
return
}
slotsfh, err = os.OpenFile(slotsfilename, os.O_WRONLY|os.O_SYNC, 0666)
if err != nil {
return
}
defer slotsfh.Close()
slotsfh.Truncate(0)
slotsfh.WriteString(dtb_name)
return
}
func AddDeviceTreeOverlayIfNotAlreadyLoaded(dtb_name string) (err error) {
slot, err := FindDeviceTreeOverlaySlot(dtb_name)
if slot == -1 && err != nil {
return AddDeviceTreeOverlay(dtb_name)
} else {
return ERROR_DTO_ALREADY_LOADED
}
}
func FindDeviceTreeOverlaySlot(dtb_name string) (slotnum int64, err error) {
var slotsfilename string
var slotsfh *os.File
var re *regexp.Regexp
re, err = regexp.Compile(`^\s*(\d+): .*,` + dtb_name + "\n$")
if err != nil {
return
}
slotsfilename, err = findSlotsFile()
if err != nil {
return
}
slotsfh, err = os.OpenFile(slotsfilename, os.O_RDONLY|os.O_SYNC, 0666)
if err != nil {
return
}
defer slotsfh.Close()
slotsfh.Seek(0, 0)
slotsreader := bufio.NewReader(slotsfh)
var line string
for line, err = slotsreader.ReadString('\n'); err == nil; line, err = slotsreader.ReadString('\n') {
if match := re.FindStringSubmatch(line); match != nil {
slotnum, err = strconv.ParseInt(match[1], 10, 64)
return
}
}
return -1, fmt.Errorf("DeviceTreeOverlay %s not found in slots\n", dtb_name)
}
func RemoveDeviceTreeOverlay(dtb_name string) (err error) {
var slotnum int64
slotnum, err = FindDeviceTreeOverlaySlot(dtb_name)
if err != nil {
return err
}
var slotsfilename string
var slotsfh *os.File
slotsfilename, err = findSlotsFile()
if err != nil {
return
}
slotsfh, err = os.OpenFile(slotsfilename, os.O_RDWR|os.O_SYNC, 0666)
if err != nil {
return
}
defer slotsfh.Close()
slotsfh.Truncate(0)
slotsfh.WriteString(fmt.Sprintf("-%d\n", slotnum))
return
}
// Newer Universal Overlays allow the pinmux to be set by writing
// "gpio", "pwm", "default", "spi", "i2c", .. to the state file for a certain pin
//
// while overlays like PyBBIO-gpio.* can, once loaded, be configured using file /sys/devices/ocp.\d/PyBBIO-gpio.*.\d\d/state
// usually the following values can be written to configure the state:
// "mode_0b00101111" => INPUT, No Pullup/down
// "mode_0b00110111" => INPUT, Pullup
// "mode_0b00100111" => INPUT, Pulldown
// "mode_0b00001111" => OUTPUT, No Pullup/down
// "mode_0b00010111" => OUTPUT, Pullup
// "mode_0b00000111" => OUTPUT, Pulldown
func SetOverlayState(dtb_name, state string) (err error) {
var overlaystatefile string
var statefh *os.File
overlaystatefile, err = findOverlayStateFile(dtb_name)
if err != nil {
return err
}
statefh, err = os.OpenFile(overlaystatefile, os.O_WRONLY|os.O_SYNC, 0666)
if err != nil {
return
}
defer statefh.Close()
statefh.Truncate(0)
statefh.WriteString(state)
return
}