blob: 8131122f972a83d38989895f1a5686d45e8418a1 [file] [log] [blame]
Enrico Granata60a818d2019-05-09 09:56:09 -07001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <memory>
6#include <string>
7
8#include <base/files/file_util.h>
9#include <base/logging.h>
10
11#include "mems_setup/iio_channel_impl.h"
12#include "mems_setup/iio_context_impl.h"
13#include "mems_setup/iio_device_impl.h"
14
15namespace mems_setup {
16
17IioDeviceImpl::IioDeviceImpl(IioContextImpl* ctx, iio_device* dev)
18 : IioDevice(), context_(ctx), device_(dev) {
19 CHECK(context_);
20 CHECK(device_);
21}
22
23IioContext* IioDeviceImpl::GetContext() const {
24 return context_;
25}
26
27const char* IioDeviceImpl::GetName() const {
28 return iio_device_get_name(device_);
29}
30
31const char* IioDeviceImpl::GetId() const {
32 return iio_device_get_id(device_);
33}
34
35base::FilePath IioDeviceImpl::GetPath() const {
36 auto path = base::FilePath("/sys/bus/iio/devices").Append(GetId());
37 CHECK(base::DirectoryExists(path));
38 return path;
39}
40
41base::Optional<std::string> IioDeviceImpl::ReadStringAttribute(
42 const std::string& name) const {
43 char data[1024] = {0};
44 ssize_t len = iio_device_attr_read(device_, name.c_str(), data, sizeof(data));
45 if (len < 0) {
46 LOG(WARNING) << "Attempting to read attribute " << name
47 << " failed: " << len;
48 return base::nullopt;
49 }
50 return std::string(data, len);
51}
52
53base::Optional<int64_t> IioDeviceImpl::ReadNumberAttribute(
54 const std::string& name) const {
55 long long val = 0; // NOLINT(runtime/int)
56 int error = iio_device_attr_read_longlong(device_, name.c_str(), &val);
57 if (error) {
58 LOG(WARNING) << "Attempting to read attribute " << name
59 << " failed: " << error;
60 return base::nullopt;
61 }
62 return val;
63}
64
65bool IioDeviceImpl::WriteStringAttribute(const std::string& name,
66 const std::string& val) {
67 int error =
68 iio_device_attr_write_raw(device_, name.c_str(), val.data(), val.size());
69 if (error) {
70 LOG(WARNING) << "Attempting to write attribute " << name
71 << " failed: " << error;
72 return false;
73 }
74 return true;
75}
76bool IioDeviceImpl::WriteNumberAttribute(const std::string& name,
77 int64_t val) {
78 int error = iio_device_attr_write_longlong(device_, name.c_str(), val);
79 if (error) {
80 LOG(WARNING) << "Attempting to write attribute " << name
81 << " failed: " << error;
82 return false;
83 }
84 return true;
85}
86
87iio_device* IioDeviceImpl::GetUnderlyingIioDevice() const {
88 return device_;
89}
90
91bool IioDeviceImpl::SetTrigger(IioDevice* trigger_device) {
92 auto impl_device = trigger_device->GetUnderlyingIioDevice();
93 if (!impl_device) {
94 LOG(WARNING) << "cannot find device " << trigger_device->GetId()
95 << " in the current context";
96 return false;
97 }
98 int ok = iio_device_set_trigger(device_, impl_device);
99 if (ok) {
100 LOG(WARNING) << "Unable to set trigger for device " << GetId()
101 << " to be device " << trigger_device->GetId()
102 << ", error: " << ok;
103 return false;
104 }
105 return true;
106}
107
108IioDevice* IioDeviceImpl::GetTrigger() {
109 const iio_device* trigger;
110 int error = iio_device_get_trigger(device_, &trigger);
111 if (error) {
112 LOG(WARNING) << "Unable to get trigger for device " << GetId();
113 return nullptr;
114 }
115 const char* trigger_id = iio_device_get_id(trigger);
116 auto trigger_device = GetContext()->GetDevice(trigger_id);
117 if (trigger_device == nullptr) {
118 LOG(WARNING) << GetId() << " has trigger device " << trigger_id
119 << "which cannot be found in this context";
120 return nullptr;
121 }
122 return trigger_device;
123}
124
125IioChannel* IioDeviceImpl::GetChannel(const std::string& name) {
126 auto k = channels_.find(name);
127 if (k != channels_.end())
128 return k->second.get();
129 iio_channel* channel = iio_device_find_channel(device_, name.c_str(), true);
130 if (channel == nullptr)
131 channel = iio_device_find_channel(device_, name.c_str(), false);
132 if (channel == nullptr)
133 return nullptr;
134 channels_.emplace(name, std::make_unique<IioChannelImpl>(channel));
135 return channels_[name].get();
136}
137
138bool IioDeviceImpl::EnableBuffer(size_t count) {
139 if (!WriteNumberAttribute("buffer/length", count))
140 return false;
141 if (!WriteNumberAttribute("buffer/enable", 1))
142 return false;
143
144 return true;
145}
146
147bool IioDeviceImpl::DisableBuffer() {
148 return WriteNumberAttribute("buffer/enable", 0);
149}
150
151bool IioDeviceImpl::IsBufferEnabled(size_t* count) const {
152 bool enabled = (ReadNumberAttribute("buffer/enable").value_or(0) == 1);
153 if (enabled && count)
154 *count = ReadNumberAttribute("buffer/length").value_or(0);
155
156 return enabled;
157}
158
159} // namespace mems_setup