summaryrefslogtreecommitdiff
path: root/files/common/openwrt/sensors-init.lua
blob: f958dd2d23a0a74d22af546a9a27d56299f9dd46 (plain) (blame)
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
#!/usr/bin/lua

cjson = require "cjson.safe"
glob = require "posix.glob"
time = require "posix.time"
unistd = require "posix.unistd"

-- ############# utils ###########

function i2c_bus_path(bus)
    return string.format("/sys/bus/i2c/devices/i2c-%d", bus)
end

function i2c_device_path(bus, address)
    return string.format("/sys/bus/i2c/devices/%d-%04X", bus, address)
end

function i2c_add_device(bus, name, address)
    local f, err = io.open(i2c_bus_path(bus) .. "/new_device", "w")
    if not f then return nil, err end

    ret, err = f:write(string.format("%s 0x%02X", name, address))
    f:close()
    return ret, err
end

function i2c_delete_device(bus, address)
    local f, err = io.open(i2c_bus_path(bus) .. "/delete_device", "w")
    if not f then return nil, err end

    ret, err = f:write(string.format("0x%02X", address))
    f:close()
    return ret, err
end

function i2c_get_mux_channels(parent, address)
    local channels = {}
    local channel_paths, glob_result = glob.glob(i2c_device_path(parent, address) .. "/channel-*", 0)
    if not channel_paths then
        if glob_result == glob.GLOB_NOMATCH then return channels end
        if glob_result == glob.GLOB_ABORTED then return nil, "glob(): aborted" end
        if glob_result == glob.GLOB_NOSPACE then return nil, "glob(): no space" end
        return nil, "glob(): unknown error"
    end
    for _, channel_path in pairs(channel_paths) do
        local channel = string.match(channel_path, '/channel%-(%d+)$')
        if not channel then return nil, "unable to parse channel number from path: " .. channel_path end

        local bus_path, err = unistd.readlink(channel_path)
        if not bus_path then return nil, err end
        local bus = string.match(bus_path, '/i2c%-(%d+)$')
        if not bus then return nil, "unable to parse bus number from path: " .. bus_path end

        channels[channel] = bus
    end
    return channels
end

-- ############# main ###########

-- assert(i2c_delete_device(0, 0x70))
-- time.nanosleep({tv_sec = 0, tv_nsec = 100000000})
assert(i2c_add_device(0, "pca9548", 0x70))
local mux_channels, err = i2c_get_mux_channels(0, 0x70)
if not mux_channels then error(err) end
for ch, bus in pairs(mux_channels) do
    print(string.format("mux channel %d -> %s", ch, i2c_bus_path(bus)))
end

-- i2c_add_device(0, "ds2482", 0x18)
-- i2c_add_device(0, "ads1115", 0x48)
-- i2c_add_device(0, "bme280", 0x76)
-- i2c_add_device(0, "bmp280", 0x77)
-- i2c_add_device(0, "am2315", 0x5c)
-- i2c_add_device(0, "mcp3221", 0x4d)